home *** CD-ROM | disk | FTP | other *** search
- Name msgibm
- ; File MSGIBM.ASM
- include mssdef.h
- ; Copyright (C) 1982,1993, Trustees of Columbia University in the
- ; City of New York. Permission is granted to any individual or
- ; institution to use, copy, or redistribute this software as long as
- ; it is not sold for profit and this copyright notice is retained.
- ; Tektronix emulator for use with MS Kermit/IBM.
- ; Edit history:
- ; 2 June 1993 version 3.13
- ; 6 Sept 1991 version 3.11
- ; 2 March 1991 version 3.10
- ; Last edit 2 June 1993
- ; June 1993 store EGA images in expanded memory if available and if used
- ; for screen rollback.
- ; March 1993 Read GRight font from Code Page DOS file EGA.CPI, add CP850
- ; compressed font.
- ; Feb 1992 Add DG 470 color graphics, cursor, etc.
- ; Dec 1992 Add DG compressed fonts, line, bar, etc graphics support.
- ; August 1992 Add beginnings of Data General D463 support.
- ; 12 Nov 1990 Add text cursor symbol, and on 17 Nov add cursor on/off.
- ; 2 Nov 1990 Add Microsoft mouse direct support.
- ; 8 June 1989 Added Wyse-700 support from Mikko Laanti.
- ; 21 Nov 1988 Version 2.32
- ; 1 Nov 1987 Heavy rewrite to integrate code into regular MS Kermit/IBM
- ; material. [jrd]
- ;==============================================================================
- ; Original version for TI Pro computers by
- ; 12-Dec-84 Joe Smith, CSM Computing Center, Golden CO 80401
- ; adapted to IBM PC June 1987 by Brian Holley,
- ; Faculty of Economics and Politics
- ; University of Cambridge, England
- ; Email: BJH6@UK.AC.CAM.PHX
- ; Upgraded and integrated into MS Kermit 2.30 by Joe Doupnik, Utah State Univ.
- ;
- ; Description of Tektronix commands
- ;
- ; ESC CONTROL-E (ENQ) requests a status report
- ; ESC FORMFEED erases the screen.
- ; ESC CONTROL-X turns on bypass mode (ignore incoming characters).
- ; ESC CONTROL-Z turns on the crosshairs (not on 4006 or 4025)
- ; ESC 2 exit Tek submode for text mode (ignore if doing full Tek)
- ; ESC ? is replaced by DEL code, to assist line plots with 7 bit systems.
- ; ESC [ Pn ; Pn m set screen colors. Pn = 30 + sum of colors for foregnd,
- ; 40 + sum of colors for background, Pn = 0 sets b/w, Pn = 1 for high
- ; intensity. Colors are red = 1, green = 2, blue = 4.
- ; ESC [ ? 3 8 l exits Tek mode and returns to host text terminal type
- ; (VT102 if none defined yet). This is an extension from DEC VT340's.
- ; ESC [ ? 256 n invokes a screen size report, for Word Perfect. Report is
- ; ESC [ ? 256; height; width; num colors n where num colors is 0, 1 or
- ; 16; report ESC [ ? 24; 80; 0 n for pure text mono systems.
- ; ESC @ through ESC M sets default fill pattern as below (1=@...).
- ; ESC Z report terminal type (as VT320)
- ; ESC [ 2; 2 $ u host request color palette report.
- ; ESC / xhome;yhome;xwidth;yheight x draw an empty rectangle
- ; ESC / xhome;yhome;xwidth;yheight;pattern y fill rectangle with pattern
- ; ESC / xhome;yhome;xwidth;yheight;pattern z fill rect with pattern+border
- ; where x/yhome is the lower left Tek corner, xwidth and yheight are the
- ; Tek width and height. All values are decimal numbers.
- ; Patterns 0:use default, 1:solid, 2:grey, 3:left to right slant, 4:right to
- ; left slant, 5:horizontal lines, 6:vertical lines, 7:slanted cross-hatch,
- ; 8:vertical cross-hatch, 9:checkerboard; 10:dotted, 11:horiz herringbone,
- ; 12:vertical herringbone,13 and above:border without fill. All are tiling
- ; 8x8 pixel patterns.
- ; ESC / param a, ... ESC / param c set user definable line drawing pattern
- ; to 16 bit value of param; plot as lsb first.
- ; ESC / 2 h or l, ESC / 9 h or l. h is set, l is reset, 2 is destructive
- ; space and 9 is destructive backspace. Defaults are reset.
- ; ESC x ESC y ESC z selects one of these user definable patterns above.
- ; ESC P P1; P2; P3 q string ESC \ a Sixel Graphics command
- ; P1 and P3 ignored, P2 = 0 or 2 means draw 0 bits in background, 1 means
- ; skip them.
- ; string is
- ; sixel chars (3fh..7eh, lower 6 bits+3fh, displayed lsb at the top)
- ; ! Pn sixel char where Pn is a repeat count
- ; " Pan; Pad; Ph; Pv raster attributes (all ignored for now)
- ; # Pc; Pu; Px; Py; Pz coloring as follows
- ; Pc is color palette, 0-255 (note, only 0..15 are predefined)
- ; Pu is color units, 1=HLS, 2=RGB
- ; For Hue Lightness Saturation:
- ; Px = Hue angle, 0-360 degrees. The colors are mapped around
- ; the color wheel in 60 degree segments as Hues:
- ; 0-29 deg = blue, 30-89 = magenta (blue + red), 90-149 = red,
- ; 150-209 = yellow (red + green), 210-269 = green,
- ; 270-329 = cyan (green + blue), 330-359 = blue.
- ; Py = Lightness, 0-100%, Pz = Saturation, 0-100%
- ; Lightness Sat = 51-100 Sat = 11-50 Sat = 0-10
- ; 86-100 bold white bold white bold white
- ; 71-85 bold hue bold white bold white
- ; 57-70 bold hue grey (dim white) grey
- ; 43-56 bold hue dim hue black
- ; 29-42 dim hue grey grey
- ; 14-28 dim hue black black
- ; 0-13 black black black
- ; Note that Py = Pz = 50 gives the widest spectrum.
- ; For RGB: Px = red, 0-100%, Py = green, 0-100%, Pz = blue, 0-100%
- ; If any color exceeds 50% then the bold bit is turned on for
- ; the ensemble (IBM ega display adapter constraint for RGBi).
- ;
- ; Palette registers can be selected by the substring
- ; # Pc followed by a non-numeric char other than ";"
- ; and Pc is the palette register, 0-255.
- ;
- ; $ (dollar sign ) meaning go to left margin
- ; - (minus) meaning go to left margin 6 dots down.
- ; This command yields one or more sets of 6 vertically arranged dots. They
- ; are placed starting at the top and left side of the current text cell.
- ; Escape sequences are permitted within string and occur without disruption.
- ; CONTROL-] (GS) turns on plot mode, the first move will be with beam off.
- ; CONTROL-^ (RS) turns on incremental plot mode. RS space means move pen up
- ; RS P means move pen down, following letters: A, E, D, F, B, J, H, I mean
- ; move right, right and up, up, left and up, left, left and down, down, and
- ; right and down, respectively. Ex: RS <space> J J J means move three Tek
- ; positions left and down with the pen up (invisibly).
- ; CONTROL-UNDERLINE (US) turns off plot mode, as does CR (for all but 4025).
- ; CONTROL-X switches from TEKTRONIX sub mode to NORMAL alpha mode but is
- ; ignored if we are emulating a full Tek terminal rather than a sub mode
- ; of DEC or Heath.
- ; FF erases screen.
- ; ESC letter, where letter is accent grave (`) a..e, sets the line drawing
- ; pattern until reset to solid lines (same as escape accent) by command or
- ; a terminal reset.
- ;
- ; ENQ = Control E
- ; ESC = Control [ (left square bracket)
- ; FF = Control L
- ; FS = Control \ (backslash)
- ; GS = Control ] (right square bracket)
- ; RS = Control ^ (caret)
- ; US = Control _ (underscore)
- ;
- ; The plot commands are characters which specify the absolute position to move
- ; the beam. All moves except the one immediately after the GS character
- ; (Control-]) are with a visible trace.
- ;
- ; For 4010-like devices - The positions are from 0 to 1023 for both X and Y,
- ; although only 0 to 780 are visible for Y due to screen geometry. The screen
- ; is 10.23 by 7.80 inches, and coordinates are sent as 1 to 4 characters.
- ;
- ; For 4014-like devices - The positions are from 0 to 4096, but each movement
- ; is a multiple of 4 positions unless the high-resolution LSBXY are sent. This
- ; makes it compatible with the 4010 in that a full sized plot fills the screen.
- ;
- ; HIX,HIY = High-order 5 bits of position
- ; LOX,LOY = Middle-order 5 bits of position
- ; LSBXY = Low-order 2 bits of X + low-order 2 bits of Y (4014 mode)
- ;
- ; Hi Y Lo Y Hi X LSBXY Characters sent (Lo-X always sent)
- ; ---- ---- ---- ----- ----------------------------------
- ; Same Same Same Same Lo-X
- ; Same Same Same Diff LSB, Lo-Y, Lo-X 4014
- ; Same Same Diff Same Lo-Y, Hi-X, Lo-X
- ; Same Same Diff Diff LSB, Lo-Y, Hi-X, Lo-X 4014
- ; Same Diff Same Same Lo-Y, Lo-X
- ; Same Diff Same Diff LSB, Lo-Y, Lo-X 4014
- ; Same Diff Diff Same Lo-Y, Hi-X, Lo-X
- ; Same Diff Diff Diff LSB, Lo-Y, Hi-X, Lo-X 4014
- ; Diff Same Same Same Hi-Y, Lo-X
- ; Diff Same Same Diff Hi-Y, LSB, Lo-Y, Lo-X 4014
- ; Diff Same Diff Same Hi-Y, Lo-Y, Hi-X, Lo-X
- ; Diff Same Diff Diff Hi-Y, LSB, Lo-Y, Hi-X, Lo-X 4014
- ; Diff Diff Same Same Hi-Y, Lo-Y, Lo-X
- ; Diff Diff Same Diff Hi-Y, LSB, Lo-Y, Lo-X 4014
- ; Diff Diff Diff Same Hi-y, Lo-Y, Hi-X, Lo-X
- ; Diff Diff Diff Diff Hi-y, LSB, Lo-Y, Hi-X, Lo-X 4014
- ; Offset for byte: 20h 60h 60h 20h 40h
- ;
- ; Note that LO-Y must be sent if HI-X has changed so that the TEKTRONIX knows
- ; the HI-X byte (in the range of 20h-3fh) is HI-X and not HI-Y. LO-Y must
- ; also be sent if LSBXY has changed, so that the 4010 will ignore LSBXY and
- ; accept LO-Y. The LSBXY byte is 60h + MARGIN*10h + LSBY*4 + LSBX. (MARGIN=0)
- ;
- ;
- ;
- ; External variable tekflg and calls to tekini, tekemu, tekesc, tekcls:
- ; Byte TEKFLG is non-zero when the Tek emulator is active; it is set by the
- ; startup code in tekini and is maintained in mszibm. Internal variable
- ; inited remembers if we have a graphics screen saved, etc.
- ; TEKINI must be called when entering the emulator to establish the graphics
- ; screen mode and to calculate the screen dimensions.
- ; TEKRINT reinitialize complete emulator.
- ; TEKESC is called from say mszibm.asm to invoke Tek emulation when the
- ; external procedures have detected an Escape Control-L sequence. An implicit
- ; initialization is done if necessary.
- ; TEKEMU is the normal entry point to pass a received character to the emulator.
- ; It too will do an implicit initialization, if required.
- ; TEKCLS clears the graphics screen, but only if the emulator is active.
- ; The emulator remains active during Connect mode Help, Status, and other
- ; interrupts which do not change the terminal type.
-
-
- public tekemu,tekini,tekrint,tekend,tekgraf ; Terminal emulation
- public tekdmp, tekinq, tekpal, tekrpal ; used by mszibm file
- public chcontrol, tekcursor, tekgcptr ; used by msyibm file
- public ttxtchr,ttxtline, dgline, dgbar, teksetcursor, tekremcursor
- public cursorst, croshair, dgcrosson, dgcrossoff, dgcrossrpt
- public dgsetcrloc, dgarc, dgpoly, savegoff, saveglen, cspb2
-
- ENQ equ 05h ; ^E ENQ for TEK enquiries
- CAN equ 18h ; ^X to return to ANSI mode
- ESCZ equ 1Ah ; SUB, ESC-^Z triggers crosshairs
- VT equ 0Bh ; ^K go up one line
- CR equ 0Dh
- FS equ 1Ch ; ^\ for point plot mode
- GS equ 1Dh ; ^] draw line (1st move is invisible)
- RS equ 1Eh ; ^^ for incremental line plot mode
- US equ 1Fh ; ^_ (underscore) returns to text mode
- accent equ 60h ; accent grave
-
- txtmode equ 4 ; text mode for TEKTRONIX status
- maxtekx equ 1024 ; horizontal and
- maxteky equ 780 ; vertical resolution of TEK 4010
-
- screen equ 10h ; IBM Bios screen call
-
- uparr equ 72 ; DOS scan codes for arrow keys
- dnarr equ 80
- lftarr equ 75
- rgtarr equ 77
- homscn equ 71 ; DOS home screen scan code
- shuparr equ '8' ; ascii codes for shifted arrows
- shdnarr equ '2'
- shlftarr equ '4'
- shrgtarr equ '6'
- mouse equ 33h ; Microsoft mouse interrupt
- msread equ 3 ; mouse, read status and position
- mswrite equ 4 ; mouse, set position
- mshoriz equ 7 ; mouse, set min/max horizontal motion
- msvert equ 8 ; mouse, set min/max vertical motion
- msgetbf equ 21 ; mouse, get state buffer size
- msgetst equ 22 ; mouse, get mouse state to buffer
- mssetst equ 23 ; mouse, set mouse state from buffer
- msreset equ 33 ; mouse, software reset
-
- ; Graph_mode for different systems:
- cga equ 6 ; highest resolution mode for CGA
- mono equ 7 ; real monochrome display adapter
- colorega equ 14 ; Low-res mode, color EGA
- monoega equ 15 ; mono ega needs mode 15
- ega equ 16 ; Hi-res mode - EGA
- olivetti equ 72 ; Olivetti's Hi-res - 50 lines text
- toshiba equ 74h ; Toshiba T3100, like Olivetti
- vaxmate equ 0D0h ; DEC VAXmate II, like Olivetti
- wyse700 equ 0D3h ; Wyse-700 1280 * 400
- hercules equ 255 ; pseudo mode for Hercules graphics
- ; Note: IBM VGA modes 17 & 18, 640 by 480, can be used by setting "ega" above
- ; to 17 or 18 and modifying ybot to be 479 and ymult to be 48 at label tekin5.
- ; The code will scale everything appropriately for the new screen size, but
- ; there will be insufficient memory to retain the entire graphics image.
- ; Manual override SET TERMINAL GRAPHICS VGA accomplishes these two steps.
- ;
- ; Note: WYSE-700 mode 1024 * 780 and 1280 * 800 can be set only by
- ; manual override SET TERMINAL GRAPHICS WYSET or WYSEA, respectively.
- ; No automatic sensing for Wyse.
-
- ;; tekflg bits in byte
- ;tek_active equ 1 ; actively in graphics mode
- ;tek_tek equ 2 ; Tek terminal
- ;tek_dec equ 4 ; Tek submode of DEC terminals
- ;tek_sg equ 8 ; special graphics mode
-
- segega equ 0a000h ; segments of display memory, EGA,VGA
- segcga equ 0b800h ; CGA, AT&T/Olivetti and relatives
- seghga equ 0b000h ; HGA
- segmono equ 0b000h ; Monochrome
- segwyse equ 0a000h ; wyse-700, both banks start from here
- ; Wyse equates:
- wystoff equ 03ddh ; set bank start offset
- wystseg equ 03deh ; set bank start base
- wymode equ 03dfh ; register to select mode & bank
- wybeven equ 0c8h ; mask for R/W even bank
- wybodd equ 0cbh ; mask for R/W odd bank
-
- ; Hercules equates:
- index equ 03b4h ; 6845 index register
- cntrl equ 03b8h ; Display mode control port
- hstatus equ 03bah ; status port
- scrn_on equ 8 ; bit to turn screen on
- grph equ 2 ; graphics mode
- text equ 20h ; text mode
- config equ 03bfh ; configuration port
- genable equ 1+2 ; enable graphics (1) on two pages (2)
- rgbbold equ 80 ; nor/bold threshold for RGB intensity
- hiy equ 1 ; codes for Tek graphics components
- loy equ 2
- hix equ 4
- lox equ 3
- ; maxparam and maxinter must agree with the prime equ's in file mszibm.asm
- maxparam equ 10 ; number of ESC and DCS Parameters
- maxinter equ 10 ; number of ESC and DCS Intermediates
-
- ; Pixel basic operation codes
- pixor equ 1 ; write as foreground OR current dot
- pixbak equ 2 ; write as absolute background color
- pixxor equ 4 ; write as foreground XOR current dot
- pixfor equ 8 ; write absolute foreground color
-
- emsint equ 67h ; EMS interrupt
- xmspresent equ 4300h ; EMS presence check for XMS mgr
- emsmgrstat equ 40h ; EMS get manager status
- emsgetseg equ 41h ; EMS get segment of page frame
- emsgetnpgs equ 42h ; EMS get number free pages
- emsalloc equ 43h ; EMS get handle and allocate memory
- emsmapmem equ 44h ; EMS map memory
- emsrelease equ 45h ; EMS release mapped memory
- emsgetver equ 46h ; EMS get version number
- emssetname equ 5301h ; EMS LIM 4, set name
-
- data segment
- extrn flags:byte, rxtable:byte, vtemu:byte, vtcpage:word
- extrn tv_mode:byte, yflags:byte, low_rgt:byte, tekflg:byte
- extrn param:word, nparam:word, inter:byte, ninter:word, lparam:byte
- extrn parstate:word, pardone:word, parfail:word
- extrn dnparam:word, dparam:word, dlparam:byte, dninter:word
- extrn dinter:byte, dcsstrf:byte, emubufc:word, emubuf:byte
- extrn emubufl:word, ttyact:byte, vtclear:byte, cursor:word
- extrn dgwindcomp:byte, atctype:byte, dgcross:byte, scbattr:byte
- extrn rdbuf:byte, decbuf:byte, curattr:byte, dosnum:word
- extrn parmsk:byte, flowon:byte, flowoff:byte, flowcnt:byte
- extrn emsrbhandle:word, emsgshandle:word
-
- ; required for Hercules screen handling
-
- gtable db 35h,2dh,2eh,7 ; bytes for 6845 controller
- db 5bh,2,57h,57h ; - graphics mode
- db 2,3,0,0
-
- ttable db 61h,50h,52h,0fh ; bytes for 6845 controller
- db 19h,6,19h,19h ; - text mode
- db 2,0dh,0bh,0ch
-
- attlogo db 'OLIVETTI' ; Olivetti M24/28, AT&T 6300 rom id
- attllen equ $-attlogo ; length
- toshlogo db ' TT33110000 TTOOSSHHIIBBAA' ; Toshiba T3100 logo
- toshlen equ $-toshlogo ; length
- declogo db 'Copyright Digital Equipment Corp' ; DEC VAXmate
- declen equ $-declogo
- dumpname db 'TEKPLT.TIF',0 ; dump name
- dumplen equ $-dumpname
- dhandle dw -1 ; dump file handle
- emsgsname db 'KERMIT ',0 ; 8 byte EMS region name, + safety
- emsseg dw 0 ; segment of ems memory
- emsbytes dw 0 ; pixel bytes in ems storage
- ;;;;;;;;;;;;;;; start session save area
- even
- savegoff label word
-
- ttstate dw tektxt ; state machine control pointer
- prestate dw 0 ; previous state, across interruptions
- visible db 0 ; 0 to move, 1 to draw a line
- tek_hiy dw 0 ; Y coordinate in Tektronix mode
- tek_loy db 0
- tek_hix dw 0 ; X coordinate in Tektronix mode
- tek_lox db 0
- tek_lsb db 0 ; Low-order 2 bits of X + low Y
- ; (4014 mode)
- status db 0
- lastc db 0 ; last x/y coord fragment seen
- bnkchan db 0 ; a flag so we can select which bank
- ; to write in Wyse 1280*800 mode
- colpal db 0,9,0ch,0ah ; VT340 color palette table, IRGB
- db 0dh,0bh,0eh,7, 8,1,4,2, 5,3,6,0fh ; 16 bytes, active table
- db 256-($-colpal) dup (0) ; to make 256 entries overall
- coldef db 0,9,0ch,0ah, 0dh,0bh,0eh,7, 8,1,4,2, 5,3,6,0fh ; color def
- mondef db 0,7 dup (0fh), 8 dup (7) ; monochrome default "colors"
- havepal db 0 ; 1 if have selected palette
- masktab db 80h,40h,20h,10h,8,4,2,1 ; quicker than calculations!
- ; dashed line patterns
- linetab dw 0ffffh ; ESC accent 11111111 11111111
- dw 0aaaah ; ESC a 10101010 10101010
- dw 0f0f0h ; ESC b 11110000 11110000
- dw 0fafah ; ESC c 11111010 11111010
- dw 0ffcch ; ESC d 11111111 11001100
- dw 0fc92h ; ESC e 11111100 10010010
- dw 0ffffh ; ESC x user defined
- dw 0ffffh ; ESC y user defined
- dw 0ffffh ; ESC z user defined
- linepat dw 0ffffh ; active line pattern, from above
- ginlpsave dw 0 ; saved linepat while in GIN mode
-
- tekid db escape,'[?63;1;2;4;8;9;15c',0; VT320, level 3, etc
- ;End of init data
-
- even
- xmult dw 1 ; scaling factor for x is
- xdiv dw 1 ; xmult/xdiv
- ymult dw 1 ; scaling factor for y is
- ydiv dw 1 ; ymult/ydiv
- xmax dw 640-8 ;
- ybot dw 350-1 ;
- x_coord dw 0 ; Tek text char X coordinate
- y_coord dw 0 ; Tek text char Y coordinate
- xcursor dw 0 ; PC x_coord of text cursor symbol
- ycursor dw 0 ; PC y_coord of text cursor symbol
- save_xcor dw 0 ; save with save-screen
- save_ycor dw 0 ; ditto
- xcross dw 0 ; crosshair coordinates
- ycross dw 0
- xcenter dw 0 ; center of screen
- ycenter dw 0 ; center of screen
- crossactive db 0 ; non-zero if crosshair is active
- tekcursor db 1 ; show text cursor (non-zero)
- cursorst db 0 ; cursor state (non-zero is displayed)
- oldx dw 0 ; Tek coordinates of last point
- oldy dw 767 ; initially top left
- scalex dw 0 ; PC coord for scaled x value
- scaley dw 0 ; for scaled y value
- rectx1 dw 0 ; Rectangle PC x lower left corner
- recty1 dw 0 ; Rectangle PC y lower left corner
- rectx2 dw 0 ; Rectangle PC x width
- recty2 dw 0 ; Rectangle PC y height
- angle dw 0,0 ; arc worker area
- dgxmax dw 640-1 ; DG 470
- dgymax dw 480-1
- ;dgxmax dw 800-1 ; DG 463
- ;dgymax dw 576-1
-
- numlines dw 0 ; number of lines to fill
- charhgt dw 8 ; scan lines per character
- charwidth dw 8 ; dots across character cell
- fontlptr dd font ; pointer to high bit clear char fonts
- fontrptr dd font ; pointer to high bit set char fonts
- dotbuf db 16 dup (0) ; buffer to hold char dot pattern
- fontfile db 'EGA.CPI',0 ; DOS Code Page file, ASCIIZ
- havefont dw 0 ; holds Code Page if have GRight font
- curcharw dw 8 ; char width of cursor font
- curgcol dw 0 ; last used colors of cursor
- ; area fill material
- fill db 0 ; current fill byte pattern
- fillptr dw filpat1 ; pointer to current fill pattern
- fillist dw filpat1,filpat2,filpat3,filpat4,filpat5,filpat6,filpat7
- dw filpat8,filpat9,filpat10,filpat11,filpat12,filpat13
- dw filpat14
- numfil equ ($-fillist)/2 ; number of fill patterns
- ; fill patterns, 8 bits wide, first byte is at top of PC screen
- ; 8 bytes per pattern for 8 scan line repetition
- filpat1 db 8 dup (0ffh) ; solid fill
- filpat2 db 4 dup (0aah, 55h) ; grey (alternating dots)
- filpat3 db 80h,01h,02h,04h, 08h,10h,20h,40h ; right to left slant up
- filpat4 db 80h,40h,20h,10h, 08h,04h,02h,01h ; left to right slant up
- filpat5 db 2 dup (0,0,0aah,0) ; horizontal lines
- filpat6 db 8 dup (44h) ; vertical lines
- filpat7 db 80h,41h,22h,14h, 08h,14h,22h,41h ; slanted crosshatch
- filpat8 db 2 dup (0aah,80h,80h,80h) ; vertical crosshatch
- filpat9 db 4 dup (0f0h), 4 dup (0fh) ; checkerboard
- filpat10 db 4 dup (44h, 11h) ; dots
- filpat11 db 2 dup (10h,28h,44h,82h) ; horizontal herringbone
- filpat12 db 80h,40h,20h,10h,08h,10h,20h,40h ; vertical herringbone
- filpat13 db 8 dup (0ffh) ; first user definable fill
- filpat14 db 8 dup (0ffh) ; second user definable fill
- ; end of area fill material
- defcurpat db 0ffh,6 dup (81h),0ffh ; 8x8 def Tek cursor
- dgcurupat db 11 dup (0),0ffh,0ffh,0,0; D463/470 cursor underline pattern
- dgcurbpat db 0,12 dup (0ffh),0 ; D463/470 cursor block pattern
- dgctype db 0 ; D463/470 last written cursor type
- curmode db 0 ; screen mode before graphics
- tekgraf db 0 ; Tek graphics board selection (def=auto)
- ; local variables for LINE plotting routine
- graph_mode db 0 ; graphics video mode, default is none
- inited db 0 ; non-zero if inited (retains page)
- tekident db 0 ; Tek ident request flag
- gpage db 0 ; display adapter graphics page
- gfcol db 15 ; graphics foreground color
- gbcol db 0 ; graphics background color
- tfcol db 0 ; temp foreground color
- tbcol db 0 ; temp background color
- colortb db 0,4,2,6,1,5,3,7 ; color reversed-bit setting bytes
- ccode db pixfor ; temp for holding plot color code
- bypass db 0 ; GIN mode bypass condition (0=off)
- esctype db 0 ; first char after ESCAPE char
- bscontrol db 0 ; non-zero for destructive BS
- spcontrol db 0 ; non-zero for destructive SPACE
- chcontrol db 0 ; char-writing, 1=opaque,0=transparent
- even
- putc dw mputc ; ptr to plot a character routine
- psetup dw psetupm ; ptr to plot setup routine
- pincy dw pincym ; ptr to inc y routine
- plotptr dw pltmon ; ptr to dot plot routine
- gfplot dw bpltmon ; ptr to area-fill plot routine
- segscn dw 0b800h ; actual screen segment to use
- linelen dw 0 ; offset increment between scan lines
- temp dw 0
-
- saveglen dw ($-savegoff) ; length of z save area
- ;;;;;;;;;;;;;;;;; end of session save area
-
- ten dw 10 ; word 10 for multiplying
- mousebuf dw 0 ; segment of mouse save buffer
-
- ; TIFF version 5.0 data fields
- ; Reference: Aldus/Microsoft Technical Memorandum dated 8/8/88
- ; TIFF data item size indicators
- uchar equ 1 ; unsigned byte
- ascii equ 2 ; asciiz string byte
- integer equ 3 ; 16 bit unsigned integer
- long equ 4 ; 32 bit unsigned integer
- rational equ 5 ; 32 bit numerator, 32 bit denominator
-
- entry struc ; 12 byte image file directory entries
- dw ? ; tag
- dw integer ; type, of data item
- entcnt dd 1 ; length, count of data items
- entval dw 0 ; long value or long offset to value
- dw 0
- entry ends
-
- even ; TIFF 5.0, 8 byte header
- header dw 4949h ; 'll', low byte stored first
- dw 42 ; TIFF identification, 42 decimal
- dw nentry-header,0 ; long offset to image file directory
- ; Image File Directory
- nentry dw entrycnt ; number of entries to follow
- ; 12-byte directory entries
- newsub entry <0feh,long> ; new subfield type
- iwidth entry <100h,integer> ; image width, integer for WP 5
- ilength entry <101h,integer> ; image length, integer for WP 5
- bps entry <102h,,,4> ; bits per sample, 4=iRGB, 1=B/W
- comp entry <103h,,,1> ; compression, none
- photo entry <106h,,,3> ; photometric interpret, palette
- strip entry <111h,long,25,stripoff-header> ; offset to long strip offsets
- spp entry <115h,,,1> ; samples/pixel, 1
- rps entry <116h,long,1,25> ; long rows per strip
- sbc entry <117h,integer,25,stripbc-header> ; offset to strip byte counts
- xres entry <11ah,rational,1,xresval-header> ; x axis resolution
- yres entry <11bh,rational,1,yresval-header> ; y axis resolution
- resunit entry <128h,integer,1,1> ; resolution unit, no absolute units
- soft entry <131h,ascii,proglen,prog-header> ; software ident
- stamp entry <132h,ascii,dtlen,dandt-header> ; date and time stamp
- cmap entry <140h,integer,3*16,colmap-header> ; palette color map
- entrycnt equ ($-nentry-2+11)/12 ; compute number of entries for nentry
- dd 0 ; long offset of next directory (none)
- ; supporting data pointed at above
- prog db 'MS Kermit 300',0 ; originating program, asciiz
- proglen equ $-prog
- dandt db '1989:12:25 00:00:01',0 ; date and time format
- dtlen equ $-dandt
- xresval dw 0,0,1,0 ; two double words (top / bottom)
- yresval dw 0,0,1,0 ; two double words (top / bottom)
- stripoff dd 25 dup (0) ; long file offset for each strip
- stripbc dw 25 dup (0) ; integer byte count for each strip
- ; color map for red, green, blue; index by IRGB bits from ega sample
- colmap dw 4 dup (0), 4 dup (007ffh), 4 dup (0), 4 dup (0ffffh) ; red
- dw 2 dup (0,0,007ffh,007ffh), 2 dup (0,0,0ffffh,0ffffh) ; green
- dw 2 dup (0,007ffh,0,007ffh), 2 dup (0,0ffffh,0,0ffffh) ; blue
- tifflen equ $-header ; length of header + directory + info
- pixdata equ $ ; pixel data start here on disk
- ; end of TIFF information
-
- esctab db 33 ; table of ESC <char> dispatches
- dw escjmp ; address of table for action routines
- db ENQ,FF,CAN,CTLZ,'/' ; ^E,^L,^X,^Z,/
- db '@ABCD','EFGHI','JKLM'
- db 3fh,'PZ[\' ; '?PZ[\'
- db 60h,'abcde','fghij','klmno','xyz' ; accent, a..o,x,y,z
-
- ; Dispatch for esctab table
- even
- escjmp dw tekenq, tekcls,tekcan, tekgin,tekeseq ; ^E,^L,^X,^Z,/
- dw 14 dup (tekfill) ; '@ABCDEFGHIJKLM'
- dw tekqury,tekeseq,sendid,tekeseq,tekgotst ; '?PZ[\'
- dw 19 dup (teklpat) ; accent, a..o,x,y,z
-
- ; Final char table for ANSI escape sequences
- anstab db 21 ; number of entries
- dw ansjmp ; address of action routines
- db '@ABCD','EFGHJ','KXade','fhlmn','u'
-
- ; Dispatch for anstab table
- even
- ansjmp dw ansich, atcuu, atcud, atcuf, atcub ; '@ABCD'
- dw atcnl, atcpl, atcha, atcup, ated ; 'EFGHJ'
- dw atel, atech, atcuf, atcva, atcud ; 'KXade'
- dw atcup, escexit, escexit, tekcol, tekrid ; 'fhlmn'
- dw tekprpt ; 'u'
- data ends
-
- data1 segment
-
- ; 8*8 font for Hercules and such, CGA, and EGA
- ; - allows 43 lines, and 80 (90 for Hercules) chars per line.
- ; all printing (?) characters from <space> to <del> - two characters per line
- ; 8 bits per scan line, top line given first, 8 scan lines.
- font db 0,0,0,0,0,0,0,0, 18h,18h,18h,18h,18h,0,18h,0
- db 6ch,6ch,6ch,0,0,0,0,0, 36h,36h,7fh,36h,7fh,36h,36h,0
- db 0ch,3fh,68h,3eh,0bh,7eh,18h,0, 60h,66h,0ch,18h,30h,66h,06h,0
- db 38h,6ch,6ch,38h,6dh,66h,3bh,0, 0ch,18h,30h,0,0,0,0,0
- db 0ch,18h,30h,30h,30h,18h,0ch,0, 30h,18h,0ch,0ch,0ch,18h,30h,0
- db 0,18h,7eh,3ch,7eh,18h,0,0, 0,18h,18h,7eh,18h,18h,0,0
- db 0,0,0,0,0,18h,18h,30h, 0,0,0,7eh,0,0,0,0
- db 0,0,0,0,0,18h,18h,0, 0,06h,0ch,18h,30h,60h,0,0
- db 3ch,66h,6eh,7eh,76h,66h,3ch,0, 18h,38h,18h,18h,18h,18h,7eh,0
- db 3ch,66h,06h,0ch,18h,30h,7eh,0, 3ch,66h,06h,1ch,06h,66h,3ch,0
- db 0ch,1ch,3ch,6ch,7eh,0ch,0ch,0, 7eh,60h,7ch,06h,06h,66h,3ch,0
- db 1ch,30h,60h,7ch,66h,66h,3ch,0, 7eh,06h,0ch,18h,30h,30h,30h,0
- db 3ch,66h,66h,3ch,66h,66h,3ch,0, 3ch,66h,66h,3eh,06h,0ch,38h,0
- db 0,0,18h,18h,0,18h,18h,0, 0,0,18h,18h,0,18h,18h,30h
- db 0ch,18h,30h,60h,30h,18h,0ch, 0,0,0,7eh,0,7eh,0,0,0
- db 30h,18h,0ch,06h,0ch,18h,30h, 0,3ch,66h,0ch,18h,18h,0,18h,0
- db 3ch,66h,6eh,6ah,6eh,60h,3ch, 0,3ch,66h,66h,7eh,66h,66h,66h,0
- db 7ch,66h,66h,7ch,66h,66h,7ch, 0,3ch,66h,60h,60h,60h,66h,3ch,0
- db 78h,6ch,66h,66h,66h,6ch,78h, 0,7eh,60h,60h,7ch,60h,60h,7eh,0
- db 7eh,60h,60h,7ch,60h,60h,60h, 0,3ch,66h,60h,6eh,66h,66h,3ch,0
- db 66h,66h,66h,7eh,66h,66h,66h, 0,7eh,18h,18h,18h,18h,18h,7eh,0
- db 3eh,0ch,0ch,0ch,0ch,6ch,38h, 0,66h,6ch,78h,70h,78h,6ch,66h,0
- db 60h,60h,60h,60h,60h,60h,7eh, 0,63h,77h,7fh,6bh,6bh,63h,63h,0
- db 66h,66h,76h,7eh,6eh,66h,66h, 0,3ch,66h,66h,66h,66h,66h,3ch,0
- db 7ch,66h,66h,7ch,60h,60h,60h, 0,3ch,66h,66h,66h,6ah,6ch,36h,0
- db 7ch,66h,66h,7ch,6ch,66h,66h, 0,3ch,66h,60h,3ch,06h,66h,3ch,0
- db 7eh,18h,18h,18h,18h,18h,18h, 0,66h,66h,66h,66h,66h,66h,3ch,0
- db 66h,66h,66h,66h,66h,3ch,18h, 0,63h,63h,6bh,6bh,7fh,77h,63h,0
- db 66h,66h,3ch,18h,3ch,66h,66h, 0,66h,66h,66h,3ch,18h,18h,18h,0
- db 7eh,06h,0ch,18h,30h,60h,7eh, 0,7ch,60h,60h,60h,60h,60h,7ch,0
- db 0,60h,30h,18h,0ch,06h,0,0, 3eh,06h,06h,06h,06h,06h,3eh,0
- db 18h,3ch,66h,42h,0,0,0,0, 0,0,0,0,0,0,0,0ffh
- db 30h,18h,0ch,0,0,0,0,0, 0,0,3ch,06h,3eh,66h,3eh,0
- db 60h,60h,7ch,66h,66h,66h,7ch,0, 0,0,3ch,66h,60h,66h,3ch,0
- db 06h,06h,3eh,66h,66h,66h,3eh,0, 0,0,3ch,66h,7eh,60h,3ch,0
- db 0eh,18h,18h,3ch,18h,18h,18h,0, 0,0,3eh,66h,66h,3eh,06h,3ch
- db 60h,60h,7ch,66h,66h,66h,66h,0, 18h,0,38h,18h,18h,18h,3ch,0
- db 18h,0,38h,18h,18h,18h,18h,70h, 60h,60h,66h,6ch,78h,6ch,66h,0
- db 38h,18h,18h,18h,18h,18h,3ch,0, 0,0,76h,7fh,6bh,6bh,63h,0
- db 0,0,7ch,66h,66h,66h,66h,0, 0,0,3ch,66h,66h,66h,3ch,0
- db 0,0,7ch,66h,66h,7ch,60h,60h,0, 0,3eh,66h,66h,3eh,06h,07h
- db 0,0,6ch,76h,60h,60h,60h,0, 0,0,3eh,60h,3ch,06h,7ch,0
- db 30h,30h,7ch,30h,30h,30h,1ch,0, 0,0,66h,66h,66h,66h,3eh,0
- db 0,0,66h,66h,66h,3ch,18h,0, 0,0,63h,6bh,6bh,7fh,36h,0
- db 0,0,66h,3ch,18h,3ch,66h,0, 0,0,66h,66h,66h,3eh,06h,3ch
- db 0,0,7eh,0ch,18h,30h,7eh,0, 0ch,18h,18h,70h,18h,18h,0ch,0
- db 18h,18h,18h,0,18h,18h,18h,0, 30h,18h,18h,0eh,18h,18h,30h,0
- db 31h,6bh,46h,0,0,0,0,0, 0ffh,6 dup (81h),0ffh
- ; note, the last 8 bytes comprise the text cursor symbol pattern
-
- ; 5x14 font cell, space is on the left, 4 dot descender region
- fivedot db 14 dup (0) ; 0 null
- db 0,0,0,70h,88h,0d8h,88h,0d8h,0a8h,70h,0,0,0,0 ; 1 happy face
- db 0,0,0,70h,0f8h,0a8h,0f8h,0a8h,0d8h,70h,0,0,0,0 ; 2 happy face
- db 0,0,0,0d8h,4 dup (0f8h),70h,20h,0,0,0,0 ; 3 heart
- db 0,0,0,20h,70h,0f8h,0f8h,70h,70h,20h,0,0,0,0 ; 4 diamond
- db 0,0,0,70h,20h,0a8h,0f8h,0a8h,20h,20h,0,0,0,0 ; 5 club
- db 0,0,0,20h,70h,0f8h,0f8h,0a8h,20h,20h,0,0,0,0 ; 6 spade
- db 4 dup (0),20h,70h,70h,70h,20h,5 dup (0) ; 7 dot
- db 5 dup (0f8h),0d8h,98h,98h,0d8h,5 dup (0f8h) ; 8 floppy
- db 4 dup (0),20h,50h,98h,98h,50h,20h,0,0,0,0 ; 9 circle
- db 4 dup (0f8h),0d8h,0a8h,70h,70h,0a8h,0d8h,4 dup (0f8h) ; 10
- db 0,0,0,18h,8,20h,50h,98h,50h,20h,0,0,0,0 ; 11 male
- db 5 dup (0),20h,50h,98h,50h,20h,20h,70h,20h,0 ; 12 female
- db 0,0,0,30h,28h,20h,20h,20h,0e0h,0c0h,0,0,0,0 ; 13 note
- db 0,0,0,40h,70h,50h,70h,50h,0d0h,0d0h,30h,30h,0,0 ; 14 notes
- db 0,0,20h,98h,20h,70h,70h,20h,98h,20h,0,0,0,0 ; 15 sun
- db 0,0,0,40h,60h,70h,78h,70h,60h,40h,0,0,0,0 ; 16 rt arrow
- db 0,0,0,8,18h,38h,78h,38h,18h,8,0,0,0,0 ; 17 lft arrow
- db 0,20h,50h,98h,20h,20h,20h,98h,50h,20h,0,0,0,0 ; 18 t/b arrow
- db 0,0,6 dup (50h),0,50h,0,0,0,0 ; 19 dbl bang
- db 0,0,0,78h,0a8h,0a8h,68h,28h,28h,28h,0,0,0,0 ; 20 paragraph
- db 0,20h,50h,40h,20h,50h,20h,10h,50h,20h,0,0,0,0 ; 21 section
- db 5 dup (0),70h,70h,7 dup (0) ; 22 bar
- db 0,20h,50h,98h,20h,20h,20h,98h,50,20h,0,0f8h,0,0 ; 23 arrow,bar
- db 0,20h,50h,98h,6 dup (20h),0,0,0,0 ; 24 up arrow
- db 0,0,5 dup (20h),98h,50h,20h,0,0,0,0 ; 25 dn arrow
- db 0,0,0,20h,10h,0e8h,10h,20h,6 dup (0) ; 26 rt arrow
- db 0,0,0,20h,40h,0b8h,40h,20h,6 dup (0) ; 27 lf arrow
- db 5 dup (0),40h,40h,78h,6 dup (0) ; 28
- db 4 dup (0),50h,98h,50h,7 dup (0) ; 29
- db 4 dup (0),20h,70h,0f8h,7 dup (0) ; 30 up triang
- db 4 dup (0),0f8h,70h,20h,7 dup (0) ; 31 dn traing
- db 14 dup (0) ; space
- db 0,0,20h,20h,20h,20h,20h,0,20h,0,0,0,0,0 ; !
- db 0,0,50h,50h,50h,9 dup (0) ; "
- db 0,0,50h,50h,0f8h,50h,50h,0f8h,50h,50h,0,0,0,0 ; #
- db 0,20h,30h,60h,40h,60h,30h,30h,60h,20h,0,0,0,0 ; $
- db 0,0,0c0h,0c8h,10h,20h,40h,98h,18h,0,0,0,0,0 ; %
- db 0,20h,50h,70h,20h,68h,90h,90h,90h,68h,0,0,0,0 ; &
- db 0,0,20h,20h,20h,9 dup (0) ; '
- db 0,0,10h,20h,40h,40h,40h,40h,20h,10h,0,0,0,0 ; (
- db 0,0,40h,20h,10h,10h,10h,10h,20h,40h,0,0,0,0 ; )
- db 0,0,0,20h,0a8h,70h,70h,70h,0a8h,20h,0,0,0,0 ; *
- db 0,0,20h,20h,20h,0f8h,20h,20h,20h,0,0,0,0,0 ; +
- db 8 dup (0),10h,10h,10h,20h,0,0 ; ,
- db 5 dup (0),70h,8 dup (0) ; -
- db 8 dup (0),20h,20h,0,0,0,0 ; .
- db 0,0,0,0,08h,10h,20h,40h,80h,5 dup (0) ; /
- db 0,0,78h,48h,48h,58h,68h,48h,48h,78h,0,0,0,0 ; 0
- db 0,0,20h,60h,5 dup (20h),70h,0,0,0,0 ; 1
- db 0,0,70h,50h,10h,30h,60h,40h,40h,70h,0,0,0,0 ; 2
- db 0,0,70h,50h,10h,30h,10h,10h,50h,70h,0,0,0,0 ; 3
- db 0,0,10h,30h,30h,50h,50h,78h,10h,10h,0,0,0,0 ; 4
- db 0,0,70h,40h,40h,70h,10h,10h,50h,70h,0,0,0,0 ; 5
- db 0,0,70h,50h,40h,40h,70h,50h,50h,70h,0,0,0,0 ; 6
- db 0,0,70h,10h,10h,10h,20h,20h,40h,40h,0,0,0,0 ; 7
- db 0,0,70h,50h,50h,70h,50h,50h,50h,70h,0,0,0,0 ; 8
- db 0,0,70h,50h,50h,70h,10h,10h,50h,70h,0,0,0,0 ; 9
- db 0,0,0,20h,20h,0,0,20h,20h,5 dup (0) ; :
- db 5 dup (0),20h,20h,0,0,20h,20h,40h,0,0 ; ;
- db 0,0,08h,10h,20h,40h,20h,10h,08h,5 dup(0) ; <
- db 0,0,0,0,70h,0,70h,7 dup (0) ; =
- db 0,0,40h,20h,10h,08h,10h,20h,40h,5 dup (0) ; >
- db 0,0,70h,50h,10h,30h,20h,20h,0,20h,0,0,0,0 ; ?
- db 0,0,0,78h,88h,0b8h,0a8h,0b8h,80h,70h,0,0,0,0 ; @
- db 0,0,30h,48h,48h,48h,78h,48h,48h,48h,0,0,0,0 ; A
- db 0,0,70h,50h,48h,70h,50h,48h,48h,70h,0,0,0,0 ; B
- db 0,0,30h,48h,4 dup (40h),48h,30h,0,0,0,0 ; C
- db 0,0,70h,50h,4 dup (48h),50h,70h,0,0,0,0 ; D
- db 0,0,78h,40h,40h,70h,40h,40h,40h,78h,0,0,0,0 ; E
- db 0,0,78h,40h,40h,70h,40h,40h,40h,40h,0,0,0,0 ; F
- db 0,0,30h,48h,40h,40h,58h,48h,48h,38h,0,0,0,0 ; G
- db 0,0,48h,48h,48h,78h,48h,48h,48h,48h,0,0,0,0 ; H
- db 0,0,70h,6 dup (20h),70h,0,0,0,0 ; I
- db 0,0,38h,08h,08h,08h,08h,48h,48h,78h,0,0,0,0 ; J
- db 0,0,48h,48h,50h,60h,60h,50h,50h,48h,0,0,0,0 ; K
- db 0,0,7 dup (40h),70h,0,0,0,0 ; L
- db 0,0,48h,78h,78h,5 dup (48h),0,0,0,0 ; M
- db 0,0,48h,48h,48h,68h,58h,48h,48h,48h,0,0,0,0 ; N
- db 0,0,30h,6 dup (48h),30h,0,0,0,0 ; O
- db 0,0,70h,48h,48h,48h,70h,40h,40h,40h,0,0,0,0 ; P
- db 0,0,30h,48h,48h,48h,48h,58h,58h,30h,10h,0,0,0 ; Q
- db 0,0,70h,48h,48h,70h,50h,50h,48h,48h,0,0,0,0 ; R
- db 0,0,30h,50h,40h,60h,30h,10h,50h,60h,0,0,0,0 ; S
- db 0,0,0f8h,7 dup (20h),0,0,0,0 ; T
- db 0,0,7 dup (48h),78h,0,0,0,0 ; U
- db 0,0,6 dup (48h),30h,30h,0,0,0,0 ; V
- db 0,0,5 dup (48h),78h,78h,48h,0,0,0,0 ; W
- db 0,0,50h,50h,50h,20h,20h,50h,50h,50h,0,0,0,0 ; X
- db 0,0,88h,88h,50h,50h,20h,20h,20h,20h,0,0,0,0 ; Y
- db 0,0,78h,08h,10h,10h,20h,20h,40h,78h,0,0,0,0 ; Z
- db 0,0,70h,6 dup (40h),70h,0,0,0,0 ; [
- db 0,0,0,0,80h,40h,20h,10h,08h,5 dup (0) ; \
- db 0,0,70h,6 dup (10h),70h,0,0,0,0 ; ]
- db 0,0,20h,50h,88h,9 dup (0) ; ^
- db 10 dup (0),0f8h,0,0,0 ; _
- db 0,0,40h,60h,10h,9 dup (0) ; `
- db 5 dup (0),70h,10h,70h,50h,78h,0,0,0,0 ; a
- db 0,0,40h,40h,40h,70h,50h,50h,50h,70h,0,0,0,0 ; b
- db 5 dup (0),70h,50h,40h,50h,70h,0,0,0,0 ; c
- db 0,0,10h,10h,10h,70h,50h,50h,50h,70h,0,0,0,0 ; d
- db 5 dup (0),70h,50h,70h,40h,70h,0,0,0,0 ; e
- db 0,0,30h,20h,20h,70h,20h,20h,20h,20h,0,0,0,0 ; f
- db 5 dup (0),70h,50h,50h,70h,10h,50h,70h,0,0 ; g
- db 0,0,40h,40h,40h,70h,50h,50h,50h,50h,0,0,0,0 ; h
- db 0,0,0,20h,0,60h,20h,20h,20h,70h,0,0,0,0 ; i
- db 0,0,0,10h,0,30h,10h,10h,10h,50h,70h,0,0,0 ; j
- db 0,0,40h,40h,40h,48h,50h,60h,50h,48h,0,0,0,0 ; k
- db 0,0,60h,6 dup (20h),70h,0,0,0,0 ; l
- db 5 dup (0),0d8h,0f8h,0a8h,88h,88h,0,0,0,0 ; m
- db 5 dup (0),0f0h,4 dup (50h),0,0,0,0 ; n
- db 5 dup (0),70h,50h,50h,50h,70h,0,0,0,0 ; o
- db 5 dup (0),70h,50h,50h,50h,70h,40h,40h,0,0 ; p
- db 5 dup (0),70h,50h,50h,50h,70h,10h,10h,0,0 ; q
- db 5 dup (0),58h,60h,40h,40h,40h,0,0,0,0 ; r
- db 5 dup (0),30h,40h,20h,10h,60h,0,0,0,0 ; s
- db 0,0,20h,20h,20h,70h,20h,20h,20h,30h,0,0,0,0 ; t
- db 5 dup (0),4 dup (50h),70h,0,0,0,0 ; u
- db 5 dup (0),50h,50h,50h,20h,20h,0,0,0,0 ; v
- db 5 dup (0),88h,0a8h,0a8h,0a8h,50h,0,0,0,0 ; w
- db 5 dup (0),88h,50h,20h,50h,88h,0,0,0,0 ; x
- db 5 dup (0),4 dup (50h),30h,10h,70h,0,0 ; y
- db 5 dup (0), 70h,10h,20h,40h,70h,0,0,0,0 ; z
- db 0,0,0,30h,20h,20h,60h,20h,20h,30h,0,0,0,0 ; {
- db 0,0,8 dup (20h),0,0,0,0 ; |
- db 0,0,0,60h,20h,20h,30h,20h,20h,60h,0,0,0,0 ; }
- db 0,0,0,40h,0a8h,10h,8 dup (0) ; ~
- db 0,0,0,20h,50h,98h,98h,98h,0f8h,5 dup (0) ; 127 DEL
-
- ; begin CP437 GRight
- gr437 db 0,0,30h,48h,40h,40h,40h,40h,48h,30h,10h,70h,0,0 ; Cedillia
- db 0,0,48h,0,0,4 dup (48h),78h,0,0,0,0 ; u umlate
- db 0,0,10h,20h,0,70h,50h,70h,40h,70h,0,0,0,0 ; e accent
- db 0,0,20h,50h,0,70h,10h,70h,50h,78h,0,0,0,0 ; a caret
- db 0,0,0,50h,0,70h,10h,70h,50h,78h,0,0,0,0 ; a umlate
- db 0,0,40h,20h,0,70h,10h,70h,50h,78h,0,0,0,0 ; a accent
- db 0,20h,50h,20h,0,70h,10h,70h,50h,78h,0,0,0,0 ; a ring
- db 5 dup (0),70h,50h,40h,50h,70h,20h,60h,0,0 ; cedillia
- db 0,0,20h,50h,0,70h,50h,70h,40h,70h,0,0,0,0 ; e caret
- db 0,0,0,50h,0,70h,50h,70h,40h,70h,0,0,0,0 ; e umlate
- db 0,0,40h,20h,0,70h,50h,70h,40h,70h,0,0,0,0 ; e accent
- db 0,0,0,50h,0,60h,20h,20h,20h,70h,0,0,0,0 ; i umlate
- db 0,0,20h,50h,0,60h,20h,20h,20h,70h,0,0,0,0 ; i caret
- db 0,0,40h,20h,0,60h,20h,20h,20h,70h,0,0,0,0 ; i accent
- db 0,28h,0,30h,48h,48h,78h,48h,48h,48h,0,0,0,0 ; A umlate
- db 10h,28h,10h,30h,48h,48h,78h,48h,48h,48h,0,0,0,0 ; A ring
-
- db 10h,20h,0,78h,40h,40h,70h,40h,40h,78h,0,0,0,0 ; E accent
- db 5 dup (0),78h,0a8h,0b8h,0d0h,0b8h,0,0,0,0 ; ae
- db 0,0,78h,0a0h,0a0h,0b0h,0a0h,0e0h,0a0h,0b8h,0,0,0,0 ; AE
- db 0,0,20h,50h,0,70h,50h,50h,50h,70h,0,0,0,0 ; o caret
- db 0,0,0,50h,0,70h,50h,50h,50h,70h,0,0,0,0 ; o umlate
- db 0,0,40h,20h,0,70h,50h,50h,50h,70h,0,0,0,0 ; o accent
- db 0,0,20h,50h,0,50h,50h,50h,50h,70h,0,0,0,0 ; u caret
- db 0,0,40h,20h,0,50h,50h,50h,50h,70h,0,0,0,0 ; u accent
- db 0,0,0,50h,0,4 dup (50h),30h,10h,70h,0,0 ; y umlate
- db 0,28h,0,30h,5 dup (48h),30h,0,0,0,0 ; O umlate
- db 0,28h,0,6 dup (48h),78h,0,0,0,0 ; U umlate
- db 0,20h,20h,70h,50h,40h,50h,70h,20h,20h,0,0,0,0 ; cent sign
- db 0,30h,28h,20h,20h,70h,20h,20h,40h,78h,0,0,0,0 ; Sterling
- db 0,0,88h,88h,50h,20h,70h,20h,70h,20h,0,0,0,0 ; Yen
- db 0,0,0e0h,90h,90h,0e0h,80h,90h,0b8h,90h,18h,0,0,0 ; Piaster
- db 0,10h,28h,20h,20h,70h,20h,20h,0c0h,40h,0,0,0,0 ; Florin
-
- db 0,0,10h,20h,0,70h,10h,70h,50h,78h,0,0,0,0 ; a accent
- db 0,0,20h,40h,0,60h,20h,20h,20h,70h,0,0,0,0 ; i accent
- db 0,0,10h,20h,0,70h,50h,50h,50h,70h,0,0,0,0 ; o accent
- db 0,0,10h,20h,0,50h,50h,50h,50h,70h,0,0,0,0 ; u accent
- db 0,0,28h,50h,0,60h,50h,50h,50h,50h,0,0,0,0 ; n tilde
- db 0,28h,50h,0,48h,48h,68h,58h,48h,48h,0,0,0,0 ; N tilde
- db 0,70h,50h,78h,0,78h,8 dup (0) ; male ord
- db 0,70h,50h,70h,0,78h,8 dup (0) ; female ord
- db 0,0,10h,0,10h,10h,20h,40h,48h,30h,0,0,0,0 ; inv query
- db 5 dup (0),78h,40h,40h,6 dup (0) ; inv not
- db 5 dup (0),78h,8,8,6 dup (0) ; not
- db 40h,40h,48h,50h,20h,78h,88h,18h,20h,38h,0,0,0,0 ; one half
- db 40h,40h,48h,50h,28h,58h,0a8h,48h,78h,10h,0,0,0,0 ; one quarter
- db 0,0,0,20h,0,5 dup (20h),0,0,0,0 ; inv bang
- db 0,0,0,0,28h,50h,0a0h,50h,28h,0,0,0,0,0 ; left chevron
- db 0,0,0,0,0a0h,50h,28h,50h,0a0h,0,0,0,0,0 ; rgt chevron
-
- db 90h,48h,20h,90h,48h,20h,90h,48h,20h,90h,48h,20h,90h,48h
- db 0a8h,50h,0a8h,50h,0a8h,50h,0a8h,50h,0a8h,50h,0a8h,50h,0a8h,50h
- db 48h,0a0h,20h,48h,0a0h,20h,48h,0a0h,20h,48h,0a0h,20h,48h,0a0h
- db 14 dup (30h)
- db 5 dup (30h),0f0h,8 dup (30h)
- db 4 dup (30h),0f0h,30h,30h,0f0h,6 dup (30h)
- db 6 dup (50h),0d0h,7 dup (50h)
- db 6 dup (0),0f0h,7 dup (50h)
- db 4 dup (0),0f0h,30h,30h,0f0h,6 dup (30h)
- db 4 dup (50h),0d0h,50h,50h,0d0h,6 dup (50h)
- db 14 dup (50h) ; 186
- db 4 dup (0),0f0h,10h,10h,0d0h,6 dup (50h)
- db 4 dup (50h),0d0h,10h,10h,0f0h,6 dup (0)
- db 5 dup (50h),0f0h,8 dup (0)
- db 4 dup (30h),0f0h,30h,30h,0f0h,6 dup (0)
- db 4 dup (0),0f0h,9 dup (30h)
-
- db 5 dup (30h),038h,8 dup (0) ; 192
- db 5 dup (30h),0f8h,8 dup (0)
- db 5 dup (0),0f8h,8 dup (30h)
- db 5 dup (30h),38h,8 dup (30h)
- db 5 dup (0),0f8h,8 dup (0) ; 196
- db 5 dup (30h),0f8h,8 dup (30h)
- db 4 dup (30h),38h,30h,30h,38h,6 dup (30h)
- db 5 dup (50h),58h,8 dup (50h)
- db 4 dup (50h),58h,40h,40h,48h,6 dup (0)
- db 4 dup (0),78h,40h,40h,58h,6 dup (50h)
- db 4 dup (50h),58h,40h,40h,48h,6 dup (0)
- db 4 dup (0),0f0h,0,0,0d8h,6 dup (50h) ; 202
- db 4 dup (50h),58h,40h,40h,58h,6 dup (50h)
- db 4 dup (0),0f8h,0,0,0f8h,6 dup (0) ; 205
- db 4 dup (50h),0d8h,0,0,0d8h,6 dup (50h)
- db 5 dup (30h),0f8h,0,0f8h,6 dup (0)
-
- db 5 dup (50h),0f8h,8 dup (0)
- db 4 dup (0),0f8h,0,0,0f8h,6 dup (30h)
- db 5 dup (0),0f8h,8 dup (50h)
- db 5 dup (50h),0f8h,8 dup (0)
- db 4 dup (30h),38h,30h,30h,38h,6 dup (0)
- db 4 dup (0),38h,30h,30h,38h,6 dup (30h) ; 213
- db 5 dup (0),78h,8 dup (50h)
- db 5 dup (50h),0d8h,8 dup (50h)
- db 4 dup (30h),0f8h,0,0,0f8h,6 dup (30h)
- db 5 dup (30h),0f0h,8 dup (0)
- db 5 dup (0),38h,8 dup (30h) ; 218
- db 14 dup (0f8h)
- db 7 dup (0),7 dup (0f8h)
- db 14 dup (0e0h)
- db 7 dup (0f8h),7 dup (0)
- db 14 dup (38h)
-
- db 0,0,0,60h,98h,90h,90h,90h,98h,60h,0,0,0,0 ; Alpha
- db 0,0,70h,58h,48h,70h,50h,48h,48h,70h,40h,40h,20h,0 ; Beta
- db 0,0,78h,48h,6 dup (40h),0,0,0,0 ; Gamma
- db 0,0,0,0,0f8h,5 dup (50h),0,0,0,0 ; Pi
- db 0,0,78h,48h,20h,10h,10h,20h,48h,78h,0,0,0,0 ; Sigma
- db 0,0,0,0,78h,90h,90h,90h,90h,60h,0,0,0,0 ; sigma
- db 5 dup (0),4 dup (48h),78h,40h,40h,80h,0 ; mu
- db 0,0,0,50h,0a8h,20h,20h,20h,20h,10h,0,0,0,0 ; tau
- db 0,0,0f8h,20h,70h,98h,98h,70h,20h,0f8h,0,0,0,0 ; Phi
- db 0,0,30h,48h,48h,78h,48h,48h,48h,30h,0,0,0,0 ; Theta
- db 0,0,70h,4 dup (90h),50h,50h,0d8h,0,0,0,0 ; Omega
- db 0,0,70h,48h,20h,50h,98h,98h,98h,70h,0,0,0,0 ; delta
- db 4 dup (0),50h,98h,98h,98h,98h,50h,0,0,0,0 ; infinity
- db 0,0,30h,48h,48h,58h,68h,48h,0c8h,30h,0,0,0,0 ; phi
- db 0,0,18h,20h,40h,78h,40h,40h,20h,18h,0,0,0,0 ; epsilon
- db 0,0,0,30h,6 dup (48h),0,0,0,0 ; intersect
-
- db 0,0,0,70h,0,70h,0,70h,6 dup (0) ; defined
- db 0,0,20h,20h,70h,20h,20h,0,70h,5 dup (0) ; +/-
- db 0,40h,20h,10h,8,10h,20h,40h,0,78h,0,0,0,0 ; geq
- db 0,8,10h,20h,40h,20h,10h,8,0,78h,0,0,0,0 ; leq
- db 0,0,30h,48h,48h,40h,40h,20h,20h,5 dup (10h) ; integral top
- db 4 dup (10h),5 dup (8),48h,48h,30h,0,0 ; integral bot
- db 4 dup (0),10h,0,78h,0,10h,5 dup (0) ; divide
- db 4 dup (0),28h,50h,0,28h,50h,5 dup (0) ; approx equ
- db 0,0,30h,48h,48h,48h,30h,7 dup (0) ; open circle
- db 0,0,30h,78h,78h,78h,30h,7 dup (0) ; closed circ
- db 4 dup (0),30h,78h,78h,30h,6 dup (0) ; bullet
- db 0,0,18h,4 dup (10h),0d0h,30h,10h,0,0,0,0 ; sqrt
- db 0,10h,68h,48h,48h,48h,8 dup (0) ; super n
- db 0,20h,50h,10h,20h,40h,70h,7 dup (0) ; super 2
- db 4 dup (0),5 dup (30h),5 dup (0) ; square
- db 14 dup (0) ; 255, empty
-
- ; begin CP850 GRight
- gr850 db 0,0,30h,48h,40h,40h,40h,40h,48h,30h,10h,70h,0,0 ; Cedillia
- db 0,0,48h,0,0,4 dup (48h),78h,0,0,0,0 ; u umlate
- db 0,0,10h,20h,0,70h,50h,70h,40h,70h,0,0,0,0 ; e accent
- db 0,0,20h,50h,0,70h,10h,70h,50h,78h,0,0,0,0 ; a caret
- db 0,0,0,50h,0,70h,10h,70h,50h,78h,0,0,0,0 ; a umlate
- db 0,0,40h,20h,0,70h,10h,70h,50h,78h,0,0,0,0 ; a accent
- db 0,20h,50h,20h,0,70h,10h,70h,50h,78h,0,0,0,0 ; a ring
- db 5 dup (0),70h,50h,40h,50h,70h,20h,60h,0,0 ; cedillia
- db 0,0,20h,50h,0,70h,50h,70h,40h,70h,0,0,0,0 ; e caret
- db 0,0,0,50h,0,70h,50h,70h,40h,70h,0,0,0,0 ; e umlate
- db 0,0,40h,20h,0,70h,50h,70h,40h,70h,0,0,0,0 ; e accent
- db 0,0,0,50h,0,60h,20h,20h,20h,70h,0,0,0,0 ; i umlate
- db 0,0,20h,50h,0,60h,20h,20h,20h,70h,0,0,0,0 ; i caret
- db 0,0,40h,20h,0,60h,20h,20h,20h,70h,0,0,0,0 ; i accent
- db 0,28h,0,30h,48h,48h,78h,48h,48h,48h,0,0,0,0 ; A umlate
- db 10h,28h,10h,30h,48h,48h,78h,48h,48h,48h,0,0,0,0 ; A ring
-
- db 10h,20h,0,78h,40h,40h,70h,40h,40h,78h,0,0,0,0 ; E accent
- db 5 dup (0),78h,0a8h,0b8h,0d0h,0b8h,0,0,0,0 ; ae
- db 0,0,78h,0a0h,0a0h,0b0h,0a0h,0e0h,0a0h,0b8h,0,0,0,0 ; AE
- db 0,0,20h,50h,0,70h,50h,50h,50h,70h,0,0,0,0 ; o caret
- db 0,0,0,50h,0,70h,50h,50h,50h,70h,0,0,0,0 ; o umlate
- db 0,0,40h,20h,0,70h,50h,50h,50h,70h,0,0,0,0 ; o accent
- db 0,0,20h,50h,0,50h,50h,50h,50h,70h,0,0,0,0 ; u caret
- db 0,0,40h,20h,0,50h,50h,50h,50h,70h,0,0,0,0 ; u accent
- db 0,0,0,50h,0,4 dup (50h),30h,10h,70h,0,0 ; y umlate
- db 0,28h,0,30h,5 dup (48h),30h,0,0,0,0 ; O umlate
- db 0,28h,0,6 dup (48h),78h,0,0,0,0 ; U umlate
- db 4 dup (0),8h,78h,58h,48h,68h,78h,80h,0,0,0 ; o slash
- db 0,30h,28h,20h,20h,70h,20h,20h,40h,78h,0,0,0,0 ; Sterling
- db 0,0,0,38h,48h,58h,48h,68h,48h,0b0h,0,0,0,0 ; O slash
- db 0,0,0,88h,50h,20h,50h,88h,0,0,0,0,0,0 ; times (x)
- db 0,10h,28h,20h,20h,70h,20h,20h,0c0h,40h,0,0,0,0 ; Florin
-
- db 0,0,10h,20h,0,70h,10h,70h,50h,78h,0,0,0,0 ; a accent
- db 0,0,20h,40h,0,60h,20h,20h,20h,70h,0,0,0,0 ; i accent
- db 0,0,10h,20h,0,70h,50h,50h,50h,70h,0,0,0,0 ; o accent
- db 0,0,10h,20h,0,50h,50h,50h,50h,70h,0,0,0,0 ; u accent
- db 0,0,28h,50h,0,60h,50h,50h,50h,50h,0,0,0,0 ; n tilde
- db 0,28h,50h,0,48h,48h,68h,58h,48h,48h,0,0,0,0 ; N tilde
- db 0,70h,50h,78h,0,78h,8 dup (0) ; male ord
- db 0,70h,50h,70h,0,78h,8 dup (0) ; female ord
- db 0,0,10h,0,10h,10h,20h,40h,48h,30h,0,0,0,0 ; inv query
- db 0,0,70h,88h,0f8h,0d8h,0f8h,0d0h,70h,5 dup (0) ; registered
- db 5 dup (0),78h,8,8,6 dup (0) ; not
- db 40h,40h,48h,50h,20h,78h,88h,18h,20h,38h,0,0,0,0 ; one half
- db 40h,40h,48h,50h,28h,58h,0a8h,48h,78h,10h,0,0,0,0 ; one quarter
- db 0,0,0,20h,0,5 dup (20h),0,0,0,0 ; inv bang
- db 0,0,0,0,28h,50h,0a0h,50h,28h,0,0,0,0,0 ; left chevron
- db 0,0,0,0,0a0h,50h,28h,50h,0a0h,0,0,0,0,0 ; rgt chevron
-
- db 90h,48h,20h,90h,48h,20h,90h,48h,20h,90h,48h,20h,90h,48h
- db 0a8h,50h,0a8h,50h,0a8h,50h,0a8h,50h,0a8h,50h,0a8h,50h,0a8h,50h
- db 48h,0a0h,20h,48h,0a0h,20h,48h,0a0h,20h,48h,0a0h,20h,48h,0a0h
- db 14 dup (30h)
- db 5 dup (30h),0f0h,8 dup (30h)
- db 10h,20h,0,30h,48h,48h,78h,48h,48h,48h,4 dup (0) ; A acute
- db 10h,28h,0,30h,48h,48h,78h,48h,48h,48h,4 dup (0) ; A caret
- db 20h,10h,0,30h,48h,48h,78h,48h,48h,48h,4 dup (0) ; A grave
- db 0,70h,88h,0a8h,0d8h,0a8h,0d8h,0a8h,88h,70h,4 dup (0);copyright
- db 4 dup (50h),0d0h,50h,50h,0d0h,6 dup (50h)
- db 14 dup (50h) ; 184
- db 4 dup (0),0f0h,10h,10h,0d0h,6 dup (50h)
- db 4 dup (50h),0d0h,10h,10h,0f0h,6 dup (0)
- db 0,20h,20h,70h,50h,40h,50h,70h,20h,20h,0,0,0,0 ; cent sign
- db 0,0,88h,88h,50h,20h,70h,20h,70h,20h,0,0,0,0 ; Yen
- db 4 dup (0),0f0h,9 dup (30h)
-
- db 5 dup (30h),0f0h,8 dup (0)
- db 5 dup (30h),0f8h,8 dup (0)
- db 5 dup (0),0f8h,8 dup (30h)
- db 5 dup (30h),38h,8 dup (30h)
- db 5 dup (0),0f8h,8 dup (0) ; 196
- db 5 dup (30h),0f8h,8 dup (30h)
- db 0,0,28h,50h,0,70h,10h,70h,50h,78h,0,0,0,0 ; a tilde
- db 28h,50h,0,30h,48h,48h,78h,48h,48h,48h,0,0,0,0 ; A tilde
- db 4 dup (50h),58h,40h,40h,48h,6 dup (0)
- db 4 dup (0),78h,40h,40h,58h,6 dup (50h)
- db 4 dup (50h),58h,40h,40h,48h,6 dup (0)
- db 4 dup (0),0f0h,0,0,0d8h,6 dup (50h) ; 202
- db 4 dup (50h),58h,40h,40h,58h,6 dup (50h)
- db 4 dup (0),0f8h,0,0,0f8h,6 dup (0) ; 205
- db 4 dup (50h),0d8h,0,0,0d8h,6 dup (50h)
- db 0,88h,0,70h,88h,88h,88h,70h,0,88h,4 dup (0) ; sun/currency
-
- db 0,0,10h,60h,60h,90h,28h,48h,48h,30h,4 dup (0) ; Icelandic d
- db 0,0,70h,50h,48h,0e8h,48h,48h,50h,70h,0,0,0,0 ; Icelandic D
- db 20h,50h,0,78h,40h,40h,70h,40h,40h,78h,0,0,0,0 ; E caret
- db 0,28h,0,78h,40h,40h,70h,40h,40h,78h,0,0,0,0 ; E umlate
- db 20h,10h,0,78h,40h,40h,70h,40h,40h,78h,0,0,0,0 ; E accent
- db 3 dup (0),20h,60h,20h,20h,20h,70h,5 dup (0) ; numeral 1
- db 28h,50h,0,70h,5 dup (20h),70h,0,0,0,0 ; I tilde
- db 20h,50h,0,70h,5 dup (20h),70h,0,0,0,0 ; I caret
- db 0,50h,0,70h,5 dup (20h),70h,0,0,0,0 ; I umlate
- db 5 dup (30h),0f0h,8 dup (0)
- db 5 dup (0),38h,8 dup (30h) ; 218
- db 14 dup (0f8h)
- db 7 dup (0),7 dup (0f8h)
- db 0,4 dup (20h),0,4 dup (20h),0,0,0,0 ; v bkn bar
- db 20h,10h,0,70h,5 dup (20h),70h,0,0,0,0 ; I grave
- db 14 dup (38h)
-
- db 10h,20h,0,30h,48h,48h,48h,68h,48h,30h,0,0,0,0 ; O acute
- db 0,0,70h,58h,48h,70h,50h,48h,48h,70h,40h,40h,20h,0 ; Beta
- db 10h,28h,0,30h,48h,48h,48h,68h,48h,30h,0,0,0,0 ; O caret
- db 0,0,0,30h,48h,58h,48h,68h,48h,30h,0,0,0,0 ; O slash
- db 0,0,28h,50h,0,70h,50h,50h,50h,70,0,0,0,0 ; o tilde
- db 28h,50h,0,30h,48h,48h,48h,68h,48h,30h,0,0,0,0 ; O tilde
- db 5 dup (0),4 dup (48h),78h,40h,40h,80h,0 ; mu
- db 0,0,40h,40h,40h,70h,88h,88h,70h,40h,40h,0,0,0 ; Icelandic p
- db 0,0,40h,40h,70h,48h,48h,48h,70h,40h,40h,0,0,0 ; Icelandic P
- db 10h,20h,0,6 dup (48h),78h,0,0,0,0 ; U acute
- db 10h,28h,0,6 dup (48h),78h,0,0,0,0 ; U caret
- db 20h,10h,0,6 dup (48h),78h,0,0,0,0 ; U grave
- db 0,10h,20h,0,0,4 dup (50h),30h,10h,70h,0,0 ; y acute
- db 10h,20h,0,88h,88h,50h,20h,20h,20h,20h,0,0,0,0 ; Y acute
- db 5 dup (0),70h,8 dup (0) ; minus sign
- db 0,0,0,10h,20h,40h,8 dup (0) ; acute
-
- db 5 dup (0),70h,8 dup (0) ; minus sign
- db 0,0,20h,20h,70h,20h,20h,0,70h,5 dup (0) ; +/-
- db 4 dup (0),70h,0,70h,7 dup (0) ; equals
- db 0,0c0h,20h,40h,28h,0dh,28h,0d8h,0a8h,48h,78h,8,8,0 ; 3/4
- db 0,0,78h,0e8h,0e8h,60h,4 dup (28h),4 dup (0) ; Paragraph
- db 30h,40h,20h,70h,50h,50h,20h,10h,60h,0,0,0,0 ; section
- db 4 dup (0),10h,0,78h,0,10h,5 dup (0) ; divide
- db 6 dup (0),18h,18h,60h,5 dup (0) ; cedilla
- db 0,0,30h,48h,48h,48h,30h,7 dup (0) ; open circle
- db 4 dup (0),50h,50h,8 dup (0) ; diaerese
- db 4 dup (0),30h,78h,78h,30h,6 dup (0) ; bullet
- db 3 dup (0),20h,60h,20h,20h,20h,70h,5 dup (0) ; numeral 1
- db 0,70h,10h,30h,10h,10h,70h,7 dup (0) ; super 3
- db 0,20h,50h,10h,20h,40h,70h,7 dup (0) ; super 2
- db 4 dup (0),5 dup (30h),5 dup (0) ; square
- db 14 dup (0FH) ; 255, empty
-
-
- ; 256 * sin(x), 0..89 degrees in steps of 1 degree
- sin db 0,4,8,13,17,22,26,31,35,40,44,48,53,57,61,66,70,74,79,83,87
- db 91,95,100,104,108,112,116,120,124,128,131,135,139,143,146,150
- db 154,157,161,164,167,171,174,177,181,184,187,190,193,196,198
- db 201,204,207,209,212,214,217,219,221,223,226,228,230,232,233
- db 235,237,238,240,242,243,244,246,247,248,249,250,251,252,252
- db 253,254,254,255,255,255,255,255
-
- data1 ends
-
- code segment ; main body code segment
- extrn outchr:near, beep:near, cmblnk:near
- extrn cptchr:near, clrbuf:near, iseof:near, unique:near
- extrn pcwait:near, spath:near
-
- assume cs:code, ds:data, es:nothing
-
- ; These far routines are called by the Tek emulator; they are here to provide
- ; a bridge to the main code segment near procedures.
-
- ; Procedures for calling to the main body of MS Kermit. Most are FAR and
- ; must be in in code segment named code, not in code2.
-
- outmodem proc far ; send Tek char out serial port
- push ax
- mov ah,al
- call outchr ; outchr works from ah
- mov ax,50 ; 50 millsecond pause
- call pcwait
- pop ax
- ret
- outmodem ENDP
-
- tekbeep proc far ; sound a beep from Tek mode
- call beep
- ret
- tekbeep endp
-
- tcmblnk proc far ; blank the screen from Tek mode
- call cmblnk
- ret
- tcmblnk endp
-
- tcptchr proc far ; call session logger while in Tek
- call cptchr ; mode
- ret
- tcptchr endp
-
- tiseof proc far ; call iseof while in Tek mode
- call iseof
- ret
- tiseof endp
-
- tunique proc far ; reach to real unique name procedure
- call unique ; while in Tek mode
- ret
- tunique endp
-
- tekwait proc far ; call pcwait while in Tek mode
- call pcwait
- ret
- tekwait endp
-
- ; Return in BX the offset of the master color palette table. Used by SET TERM
- ; GRAPHICS COLOR <color value> to obtain foreground and background colors
- ; in palette slots 7 and 0, resp.
- tekgcptr proc near
- mov tekident,1 ; say this is an ident request
- call far ptr tekini ; do init steps to get screen sizes
- mov bx,offset mondef ; default monochrome colors
- cmp plotptr,offset pltcga ; using CGA style graphics?
- je tekgcpt1 ; e = yes
- cmp graph_mode,mono ; pure mono text system?
- je tekgcpt1 ; e = yes
- cmp graph_mode,monoega ; ega, but monochrome?
- je tekgcpt1 ; e = no
- mov bx,offset coldef ; return offset of color palette
- tekgcpt1:mov havepal,0 ; say don't have a palette setup
- mov tekident,0
- mov inited,0
- ret
- tekgcptr endp
-
- ; These routines can be called by either the main body or from within Tek
- ; mode.
- tekdmp proc near ; Tek screen dump routine
- call far ptr dump ; callable from main body
- clc
- ret
- tekdmp endp
-
- fspath proc far
- call spath
- ret
- fspath endp
- code ends
-
- code1 segment
- extrn scrseg:near, atparse:near, frepaint:far
- assume cs:code1
-
- ; Return screen info for Tek screen report: ax=screen height, bx=width,
- ; cx=number of colors (0=none for pure text, 1=b/w, 16=ega)
- tekinq proc near
- mov tekident,1 ; say this is an ident request
- call far ptr tekini ; do init steps to get screen sizes
- mov ax,ybot ; lowest screen line
- inc ax ; screen height, in lines
- mov bx,xmax
- add bx,8 ; screen width, in dots
- cmp graph_mode,mono ; pure text mono (no graphics at all)?
- jne tekinq1 ; ne = no
- mov ax,24 ; bottom screen line
- mov bx,80 ; screen width
- xor cx,cx ; pure mono, say 0 colors
- jmp short tekinq2
- tekinq1:mov cx,1 ; say b/w screen
- cmp plotptr,offset pltcga ; using CGA style graphics?
- je tekinq2 ; e = yes
- cmp graph_mode,monoega ; monochrome monitor on ega?
- je tekinq2 ; e = yes
- mov cx,16 ; say 16 colors
- tekinq2:mov tekident,0
- ret
- tekinq endp
-
- tparstart proc far ; start escape sequence parser
- mov parstate,0 ; set to initialize automatically
- mov pardone,offset tpardone ; jmp to this when completed
- mov parfail,0 ; no failure case jump
- ret
- tparstart endp
-
- tparser proc far
- call atparse ; reach to real parser
- ret
- tparser endp
-
- tpardone proc near ; called by real parser
- call far ptr xpardone
- ret
- tpardone endp
-
- tekpal proc near ; do palette report tekrpt
- call far ptr tekrpt ; callable from main body
- ret
- tekpal endp
-
- tekrpal proc near ; restore color palette
- call far ptr tekxco4 ; callable from main body
- ret
- tekrpal endp
-
- tscrseg proc far ; get video segment while in Tek mode
- call scrseg
- ret
- tscrseg endp
-
- code1 ends ; main body code segment
-
- ; Code segment code2 is allocated to Tektronix emulation
- code2 segment ; supplementary code segment
-
- assume cs:code2, ds:data, es:nothing
-
- cspb2 db 256 dup (0) ; code2 segment patch buffer
-
- tekxco4 proc FAR ; call local tekgco4, return far
- call tekgco4
- ret
- tekxco4 endp
-
- ; Initialise TEK mode by setting high resolution screen, etc
- tekini proc far
- push ax ; do presence tests
- push bx
- push cx
- push dx
- push si
- push di
- push es
- cmp tekident,0 ; just identifying?
- jne tekin0 ; ne = yes
- mov al,flowoff
- or al,al ; able to do xoff?
- jz tekin0 ; z = no
- call outmodem ; tell host xoff while we change modes
- tekin0: test tekflg,tek_active ; active now?
- jnz tekin2 ; nz = yes
- cmp inited,0 ; inited yet?
- jne tekin2 ; ne = yes, use existing coloring
- mov ax,linetab ; get default line pattern
- mov linepat,ax ; init active line pattern
- mov fillptr,offset filpat1 ; init active fill pointer
- cmp havepal,0 ; have a color palette yet?
- jne tekin0a ; ne = yes
- mov bx,vtemu.att_ptr ; emulator screen color ptr
- mov al,[bx]
- mov gfcol,al ; save foreground color
- and gfcol,0fh ; save just foreground bits
- and al,70h ; select background color, no bold
- mov cl,4
- shr al,cl ; get background colors
- mov gbcol,al ; set graphics background color
- tekin0a:mov ah,15 ; get current screen mode
- int screen
- and al,not 80h ; strip "preserve regen" bit 80h
- cmp al,mono ; mono text mode (7)?
- je tekin1 ; e = yes
- cmp tekident,0 ; doing an ident request?
- jne tekin2 ; ne = yes, don't mess with screen
- tekin1: mov curmode,al ; save mode here
- mov ah,3 ; get cursor position
- xor bh,bh ; page 0
- int screen
-
- ; Presence tests.
- tekin2: mov graph_mode,cga ; Color. Assume CGA
- mov segscn,segcga ; assume cga screen segment
- mov gpage,0 ; graphics page 0 but no page 1
- mov word ptr fontlptr,offset font ; offset of in-built 8x8 font
- mov word ptr fontlptr+2,seg font ; segment
- cmp word ptr fontrptr+2,0 ; have a GRight now?
- jne tekin2e ; ne = yes
- mov word ptr fontrptr+2,seg font ; no high bit set font
- mov word ptr fontrptr,offset font
- tekin2e:mov charhgt,8 ; 8 scan lines/char
- mov charwidth,8 ; 8 dots across each char
- mov putc,offset gputc ; CGA character display routine
- mov gfplot,offset bpltcga ; CGA area fill routine
- mov psetup,offset psetupc ; CGA plot setup routine
- mov plotptr,offset pltcga ; CGA dot plot routine
- mov pincy,offset pincyc ; CGA inc y routine
- mov xmult,5 ; CGA. Scale TEK to PC by 640/1024
- mov xdiv,8 ; so that 0-1023 converts to 0-639
- mov ax,640
- sub ax,charwidth
- mov xmax,ax ; x-coord of rightmost character
- mov ymult,10 ; vertical scale for IBM is 200/780
- mov ydiv,39 ;
- mov ybot,199 ; Bottom of screen is Y=199
- mov al,tekgraf ; user video board specification
- or al,al ; auto-sensing?
- jnz tekin2d ; nz = no
- jmp tekin2c ; yes (default)
- tekin2d:cmp al,1 ; user wants CGA?
- jne tekin2a ; ne = no
- jmp tekin13 ; do CGA
- tekin2a:cmp al,4 ; user wants Hercules?
- jne tekin2b ; ne = no
- jmp tekin8 ; do Hercules
- tekin2b:cmp al,5 ; user wants AT&T style?
- jne tekinwy ; ne = no
- jmp tekin7 ; do AT&T kind
- ; Wyse-700
- tekinwy:cmp al,8 ; user wants Wyse-700 1024*780 ?
- jne tekinw0 ; ne = no
- call chkwyse ; presence test
- jc tekinwf ; c = failed
- mov ax,1024
- sub ax,charwidth
- mov xmax,ax ; x-coord of rightmost character
- mov ybot,779 ; Bottom of screen is Y=780
- mov xmult,1 ; Wyse. Scale TEK to PC by 1024/1024
- mov xdiv,1 ; so that 0-1023 converts to 0-1023
- mov ymult,1 ; vertical scale is 780/780
- mov ydiv,1 ;
- jmp short tekinw2 ;
- tekinw0:cmp al,7 ; user wants Wyse-700 1280*780 ?
- jne tekinw1 ; ne = no
- call chkwyse ; presence test
- jc tekinwf ; c = failed
- mov ax,1280
- sub ax,charwidth
- mov xmax,ax ; x-coord of rightmost character
- mov ybot,779 ; Bottom of screen is Y=800
- mov xmult,10 ; Wyse. Scale TEK to PC by 1280/1024
- mov xdiv,8 ; so that 0-1023 converts to 0-1279
- mov ymult,1 ; vertical scale is 780/780
- mov ydiv,1 ;
- jmp short tekinw2 ;
- tekinwf:jmp tekin2c ; failure jump point
- tekinw1:cmp al,6 ; user wants Wyse-700 1280*800 ?
- jne tekin2c ; no = no
- call chkwyse ; presence test
- jc tekinwf ; c = failed
- mov ax,1280
- sub ax,charwidth
- mov xmax,ax ; x-coord of rightmost character
- mov ybot,799 ; Bottom of screen is Y=800
- mov xmult,10 ; Wyse. Scale TEK to PC by 1280/1024
- mov xdiv,8 ; so that 0-1023 converts to 0-1279
- mov ymult,40 ; vertical scale for IBM is 800/780
- mov ydiv,39 ; so scale those 20 pixels more
- tekinw2:mov graph_mode,wyse700 ; Assume Wyse Graphics
- mov segscn,segwyse ; assume wyse screen segment
- mov gpage,0 ; only one graphics page 0
- mov putc,offset gputc ; CGA character display routine
- mov psetup,offset psetupw ; Wyse plot setup routine
- mov plotptr,offset pltcga ; CGA dot plot routine
- mov pincy,offset pincyw ; Wyse inc y routine
- jmp tekin13 ; do Wyse
- ; do auto-sensing of display board
- ; test for EGA
- tekin2c:mov ax,1200H ; EGA: Bios alternate select
- mov bl,10H ; Ask for EGA info
- mov bh,0ffH ; Bad info, for testing
- mov cl,0fH ; Reserved switch settings
- int screen ; EGA, are you there?
- and cl,0fh ; four lower switches
- cmp cl,0cH ; Test reserved switch settings
- jb tekin3 ; b = ega present
- jmp tekin7 ; else no EGA, check other adapters
-
- tekin3: mov ax,40h ; check Bios 40:87h for ega being
- mov es,ax ; the active display adapter
- test byte ptr es:[87h],8 ; is ega active?
- jz tekin3a ; z = yes
- jmp tekin7 ; ega is inactive, check others
- tekin3a:cmp bl,1 ; is there 128KB on ega board?
- jb tekin4 ; b = less, so no screen saves
- mov gpage,1 ; >=128 KB, use two graphics pages
- tekin4: mov graph_mode,ega ; assume high resolution color
- cmp cl,3 ; high resolution color?
- je tekin5 ; e = yes
- cmp cl,9 ; high resolution color?
- je tekin5 ; e = yes
- mov graph_mode,monoega ; assume mono monitor on ega board
- test bh,1 ; ega mono mode in effect?
- jnz tekin5 ; nz = yes
- mov graph_mode,colorega ; say ordinary cga on ega board, 64KB
- mov gpage,1 ; is enough memory with 200 scan lines
- jmp short tekin5a ; use current cga parameters
- tekin5: mov ybot,349 ; text screen bottom is 349 on EGA
- mov ymult,35 ;
- mov ydiv,78 ; scale y by 350/780
- tekin5a:mov segscn,segega ; use ega screen segment
- mov psetup,offset psetupe ; plot setup routine
- mov plotptr,offset pltega ; ega dot plot routine
- mov gfplot,offset bpltega ; ega area fill routine
- mov pincy,offset pincye ; inc y routine
- mov putc,offset gputc ; character display routine
- test tekflg,tek_sg ; special graphics?
- jz tekin5d ; z = no, use Tek 8x8 font
- mov bh,2 ; 8x14 ROM double dot (EGA, 640x350)
- mov charhgt,14 ; 8x14 dots
- mov ax,1130h ; char generator routines, info req
- int screen ; returns es:bp, cx, and dl (rows)
- mov word ptr fontlptr,bp ; offset of GLeft font table
- mov ax,es
- mov word ptr fontlptr+2,ax ; segment of font table
- mov cx,vtcpage ; terminal emulation code page
- cmp cx,437 ; using CP437?
- je tekin5b ; e = yes, then have the font
- cmp havefont,cx ; do we have this font?
- je tekin5d ; e = yes
- mov havefont,cx ; set rememberance flag, even if bad
- push ax ; save hardware pointer
- push bp
- call getfont ; try to get new GRight font for CP
- pop bp
- pop ax
- jnc tekin5d ; nc = success
- tekin5b:mov word ptr fontrptr+2,ax ; segment of hardware font table
- add bp,128*14
- mov word ptr fontrptr,bp ; offset of GRight part
- tekin5d:jmp tekin13 ; end of EGA part, do VGA tests below
-
- tekin7: mov ax,0fc00h ; Olivetti/AT&T 6300, check rom id
- mov es,ax
- xor di,di ; start here
- mov graph_mode,olivetti ; Olivetti
- mov cx,attllen ; length of logo
- mov si,offset ATTLOGO ; master string
- repe cmpsb ; do a match
- je tekin7c ; e = a match
- mov di,0050h ; look here too
- mov si,offset ATTLOGO
- mov cx,attllen
- repe cmpsb
- je tekin7c ; e = a match
- mov di,2014h ; and look here
- mov si,offset ATTLOGO
- mov cx,attllen
- repe cmpsb ; do a match
- je tekin7c ; e = a match, else try other types
- tekin7a:mov graph_mode,toshiba
- mov ax,0f000h ; Check for Toshiba T3100, rom scan
- mov es,ax
- mov di,0014h ; start here
- mov si,offset TOSHLOGO ; master string
- mov cx,toshlen ; length
- repe cmpsb ; do a match
- je tekin7c ; e = a match, else try other types
- tekin7b:mov graph_mode,vaxmate ; DEC VAXmate II
- mov ax,0f000h ; Check for VAXmate II rom signature
- mov es,ax
- mov di,0e000h ; start here
- mov si,offset DECLOGO ; master string
- mov cx,declen ; length
- repe cmpsb ; do a match
- jne tekin7d ; ne = mismatch, try other types
-
- ; Olivetti/AT&T, Toshiba, VAXmate
- tekin7c:mov gpage,0 ; only page 0 with 640 by 400 mode
- mov segscn,segcga ; use cga screen segment (0b800h)
- mov psetup,offset psetupo ; plot setup routine
- mov plotptr,offset pltcga ; cga dot plot routine
- mov gfplot,offset bpltcga ; area fill plot routine
- mov pincy,offset pincyh ; inc y routine (Herc style addresses)
- mov putc,offset gputc ; character display routine
- mov ybot,399 ; bottom of screen is y = 399
- mov ymult,20 ; vertical scale = 400/780
- mov ydiv,39 ; same as cga setup
- jmp tekin13
-
- tekin7d:cmp curmode,mono ; mono text mode?
- je tekin8 ; e = yes
- jmp tekin11 ; ne = no, try cga
- ; test for Hercules
- tekin8: cmp tv_mode,1 ; Environment active?
- jne tekin8a ; ne = no, ok to test for Hercules
- jmp tekin10 ; don't do Herc mode, do Mono
- tekin8a:mov dx,hstatus ; Herc status port
- in al,dx ; read it
- mov bl,al ; save here
- and bl,80h ; remember retrace bit
- mov cx,0ffffh ; do many times (for fast machines)
- tekin8b:mov dx,hstatus ; check status port
- in al,dx
- and al,80h ; select bit
- jmp $+2 ; use a little time
- cmp bl,al ; did it change?
- loope tekin8b ; test again if not
- je tekin10 ; e = no change in bit, not Herc
- mov graph_mode,hercules ; say have Herc board
- mov segscn,seghga ; assume hga screen segment
- mov putc,offset gputc ; character display routine
- mov gfplot,offset bpltcga ; area fill plot routine
- mov psetup,offset psetuph ; plot setup routine to use
- mov plotptr,offset pltcga ; use cga dot plot routine for Herc
- mov pincy,offset pincyh ; inc y routine
- mov xmult,45 ; Scale TEK to Hercules by 720/1024
- mov xdiv,64 ; so that 0-1023 converts to 0-719
- mov ax,720
- sub ax,charwidth
- mov xmax,ax ; x-coord of rightmost character
- mov ymult,87 ; vertical scale for Hercules is
- mov ydiv,195 ; 348/780
- mov ybot,347 ; bottom of screen is y = 347
- mov ax,seghga ; segment of Herc video display
- mov es,ax
- mov al,es:[8000h] ; read original contents, page 1
- not byte ptr es:[8000h] ; write new pattern
- mov ah,es:[8000h] ; read back
- not byte ptr es:[8000h] ; restore original contents
- not ah ; invert this too
- cmp ah,al ; same (memory present?)
- jne tekin9 ; ne = not same, no memory there
- mov gpage,1 ; say two pages of display memory
- tekin9: jmp tekin13
- ; set to MONO
- tekin10:mov graph_mode,mono ; force monochrome adapter text
- mov segscn,segmono ; assume mono screen segment
- call tscrseg ; Environments: get virtual screen
- mov segscn,ax ; seg returned in ax and es:di
- mov gpage,0
- mov putc,offset mputc ; character display routine
- mov psetup,offset psetupm ; plot setup routine to use
- mov gfplot,offset bpltmon ; area fill plot routine
- mov plotptr,offset pltmon ; use hga dot plot routine
- mov pincy,offset pincym ; inc y routine
- mov xmult,5 ; Scale TEK to mono by 640/1024
- mov xdiv,8 ; so that 0-1023 converts to 0-639
- mov ax,640
- sub ax,charwidth
- mov xmax,ax ; x-coord of rightmost character
- mov ymult,10 ; vertical scale for mono is 200/780
- mov ydiv,39
- mov ybot,200 ; bottom of screen is y = 200 for Bios
- jmp tekin13 ; Uses TEXT mode, for safety
-
- ; test for CGA
- tekin11:mov graph_mode,cga ; set CGA high resolution graphics
- mov segscn,segcga ; CGA screen segment
- jmp tekin13
-
- ; Set Graphics mode
- tekin13:cmp tekident,0 ; just identifying?
- je tekin13b ; e = no
- jmp tekin16 ; ne = yes
- tekin13b:cmp graph_mode,wyse700 ; Wyse ?
- jne tekin13a ; ne = no
- call wygraf ; set Wyse graphics mode, clear regen
- jmp tekin16 ; restore screen
- tekin13a:cmp graph_mode,hercules ; Hercules?
- jne tekin14 ; ne = no
- call hgraf ; set Herc graphics mode, clear regen
- or tekflg,tek_active ; say becoming active
- jmp tekin16 ; restore screen
- tekin14:xor ah,ah ; set screen mode
- mov al,graph_mode ; to this screen mode
- test flags.vtflg,ttd463+ttd470 ; D463/D470?
- jnz tekin14a ; nz = yes, use EGA modes
- cmp tekgraf,3 ; user wants "VGA" modes (640x480)?
- jne tekin14a ; ne = no
- push ax
- mov ax,1a00h ; VGA, read display config code
- int screen
- pop ax
- cmp bl,0bh ; MCGA mono?
- jne tekin14b ; ne = no
- mov al,monoega
- mov graph_mode,al
- jmp short tekin14c
- tekin14b:cmp bl,0ch ; MCGA color?
- jne tekin14d ; ne = no
- mov al,ega
- mov graph_mode,al
- tekin14c:mov ydiv,78 ; scale y by 350/780
- mov segscn,segega ; use ega screen segment
- mov psetup,offset psetupe ; plot setup routine
- mov plotptr,offset pltcga ; ega dot plot routine
- mov gfplot,offset bpltcga ; ega area fill routine
- mov pincy,offset pincye ; inc y routine
- mov putc,offset gputc ; character display routine
- tekin14d:cmp al,monoega ; yes, allow high resolution stuff?
- jb tekin14a ; b = no
- cmp al,ega ; ditto
- ja tekin14a ; a = no
- add al,2 ; use modes 17(b/w) and 18(10)(color)
- mov ybot,479 ; text screen bottom is 479 on VGA
- mov ymult,48
- tekin14a:cmp tekident,0 ; just identifying screen size etc?
- jne tekin16 ; ne = yes, do not invoke graphics
- cmp gpage,0 ; only page 0 available?
- je tekin15 ; e = yes, and watch for Bios errors
- cmp inited,0 ; first time through?
- je tekin15 ; e = yes, clear the page of old junk
- test tekflg,tek_sg ; special graphics
- jnz tekin15 ; nz = yes, always repaints
- or al,80h ; save regen buffer (save area too)
-
- tekin15:int screen ; Bios Set Mode.
- mov ax,40h ; DOS 4 GRAPHICS.COM may see high bit
- mov es,ax ; and be confused. Clear it from Bios
- and byte ptr es:[49h],7fh ; word area for some clones
- or tekflg,tek_active ; say becoming active
- mov dgxmax,640-1 ; D470 color
- mov dgymax,480-1
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz tekin16 ; z = no
- or tekflg,tek_sg ; say special graphics mode
- cmp flags.vtflg,ttd470 ; correct guess?
- je tekin16 ; e = yes
- mov dgxmax,800-1 ; D463 monochrome
- mov dgymax,576-1
-
- tekin16:cmp tekident,0 ; just identifying?
- jne tekin16a ; ne = yes
- cmp inited,0 ; inited yet?
- jne tekin19 ; ne = yes, restore screen
- mov ttstate,offset tektxt ; do displayable text
- mov prestate,offset tektxt ; set a previous state of text
- mov inited,1 ; say we have initialized
- jmp short tekin16b ; and init the color palette
- tekin16a:mov si,offset colpal ; active color palette
- cmp havepal,0 ; have a color palette yet?
- jne tekin17 ; yes, use active palette
- tekin16b:mov si,offset mondef ; default monochrome colors
- cmp plotptr,offset pltcga ; using CGA style graphics?
- je tekin17 ; e = yes
- cmp graph_mode,mono ; pure mono text system?
- je tekin17 ; e = yes
- cmp graph_mode,monoega ; ega, but monochrome?
- je tekin17 ; e = no
- mov si,offset coldef ; use color palette
- tekin17:mov havepal,1 ; say have a color palette
- mov al,[si+7] ; foreground color = palette 7
- mov gfcol,al
- mov al,[si] ; background color = palette 0
- mov gbcol,al
- mov cx,16
- mov di,offset colpal ; VT340 active color palette
- push es
- push ds
- pop es
- cld
- rep movsb ; reinit palette entries
- pop es
- call fixcolor ; correct color mapping for some bds
- mov al,gfcol
- mov tfcol,al ; remember current coloring
- mov al,gbcol
- mov tbcol,al
- cmp tekident,0 ; just identifying?
- jne tekin21 ; ne = yes
- test tekflg,tek_sg ; special graphics active?
- jnz tekin20 ; nz = yes
- call tekcls ; clear screen, for ega coloring
- jmp short tekin20
-
- tekin19:cmp vtclear,0 ; clear screen?
- je tekin19a ; e = no
- call tekcls ; clear screen, use existing colors
- mov vtclear,0
- jmp short tekin20
- tekin19a:test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jnz tekin19b ; nz = yes
- test tekflg,tek_sg ; special graphics active?
- jnz tekin19b ; nz = yes
- call tekrest ; restore old graphics screen
- mov ax,save_xcor ; and saved cursor
- mov x_coord,ax
- mov ax,save_ycor
- mov y_coord,ax
- tekin19b:mov al,tfcol ; and coloring
- mov gfcol,al
- mov al,tbcol
- mov gbcol,al
-
- tekin20:cmp tekident,0 ; just identifying screen size etc?
- jne tekin21 ; ne = yes, do not invoke graphics
- test tekflg,tek_sg ; special graphics?
- jz tekin20a ; z = no
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz tekin20c ; z = no
- mov al,scbattr ; get default colors
- mov cl,4
- shr al,cl ; get background color bits
- mov gbcol,al ; set the for screen clearing
- call tekcls ; clear screen for nice repainting
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jz tekin20a ; z = no
- test dgcross,1 ; is crosshair to be active?
- jz tekin20b ; z = no
- call crossini
- tekin20b:call frepaint ; repaint screen
- tekin20c:mov dx,cursor
- call teksetcursor ; set the cursor
- tekin20a:mov ax,250
- call tekwait ; 250 ms wait for display adapter
- mov al,flowon ; get flowon control byte
- or al,al ; able to send xon?
- jz tekin21 ; z = no
- call outmodem ; tell host xon
- test flags.vtflg,ttd463+ttd470 ; DG D463/D470?
- jnz tekin21 ; nz = yes
- test tekflg,tek_sg ; special graphics?
- jnz tekin21 ; nz = yes
- mov cx,seg font ; use Tek 8x8 font for non-DG work
- mov word ptr fontlptr+2,cx
- mov word ptr fontrptr+2,cx ; no high bit set font
- mov cx,offset font
- mov word ptr fontlptr,cx
- mov word ptr fontrptr,cx
- call setcursor ; set the cursor
-
- tekin21:mov al,chcontrol ; opaque/transparent char writing
- mov bscontrol,al ; set destructive BS control
- mov spcontrol,al ; set destructive SPACE control
- mov tekident,0
- mov bypass,0 ; clear Bypass flag
- clc ; clear carry for success
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- tekini endp
-
- TEKRINT proc far ; Tek reinitialization entry point
- call far ptr tekend ; exit cleanly if already in Tek mode
- xor ax,ax ; get a null
- mov inited,al ; do complete reinitialization
- mov xcenter,ax ; forget center of screen
- mov ycenter,ax
- mov x_coord,ax
- mov y_coord,ax
- mov vtclear,1 ; clear the screen
- call tekini
- ret
- TEKRINT endp
-
- ; End TEK emulation, recover previous screen
- TEKEND proc far
- mov ttstate,offset tektxt ; set an initial state
- mov prestate,offset tektxt ; and a previous state
- test tekflg,tek_active ; running as a Tek terminal now?
- jnz teknd1 ; nz = yes
- ret ; else return as is
- teknd1: call remcursor ; remove text cursor, if any
- call crossfin ; clean up crosshair activity
- test tekflg,tek_sg ; special graphics?
- jnz teknd1a ; nz = yes, do not save screen
- call teksave ; save graphics screen to page 1
- mov ax,x_coord ; save cursor location too
- mov save_xcor,ax
- mov ax,y_coord
- mov save_ycor,ax
- teknd1a:cmp graph_mode,hercules ; Hercules?
- jne teknd2 ; ne = no
- call htext ; yes then set up Hercules text mode
- teknd2: call mousexit ; restore mouse state, if any
- xor ah,ah ; set video mode
- mov al,curmode ; restore previous screen mode
- int screen ; revert to text screen mode
- mov lastc,0
- mov bypass,0 ; reset bypass condition
- mov visible,0 ; next move is invisible
- test tekflg,tek_sg ; were doing special graphics?
- jz teknd3 ; z = no
- mov inited,0 ; yes, reinit next time
- teknd3: and tekflg,not (tek_active+tek_sg) ; say we are inactive
- clc
- ret
- TEKEND ENDP
-
- ; Save EGA/VGA register and Bios info in array egadata.
- ; Returns carry clear if done, else carry set
-
- ;Terminal emulation. Enter with received character in AL.
- TEKEMU proc far ; main emulator
- call tektt ; local emulator routine
- ret
- TEKEMU endp
-
- tektt proc near
- test tekflg,tek_active ; running as a Tek device?
- jnz tektt1 ; nz = yes
- push ax
- call tekini ; init now
- pop ax
- or tekflg,tek_dec ; setup Tek submode of DEC terminal
- mov ttstate,offset tektxt ; initial state
- mov prestate,offset tektxt ; set a previous state of text
- jnc tektt1 ; nc = succeeded
- ret ; else failed to init, just return
- tektt1: test al,80h ; high bit set?
- jz tektt1a ; z = no
- cmp al,9fh ; in range for C1 controls?
- ja tektt1a ; a = no
- push ax ; save the char
- mov al,escape ; make 7-bit control version
- call tektt2 ; act on escape
- pop ax
- sub al,40h ; get second char of 7-bit control
-
- tektt1a:and al,7fh ; force Tek chars to be 7 bits
- or al,al ; NUL char?
- jnz tektt2 ; nz = no
- ret ; yes, ignore it (before logging)
- tektt2: test yflags,capt ; capturing output?
- jz tektt4 ; z = no, forget this part
- push ax ; save char
- call tcptchr ; give it captured character
- pop ax ; restore character and keep going
- tektt4: test yflags,trnctl ; debug? if so use tty mode
- jz tektt5 ; z = no
- cmp al,DEL ; DEL char?
- jne tektt4a ; ne = no
- mov al,5eh ; make DEL a caret query mark
- call outscrn
- mov al,3fh ; the query mark
- call outscrn
- ret
- tektt4a:cmp al,' ' ; control char?
- jae tektt4b ; ae = no
- push ax
- mov al,5eh ; caret
- call outscrn
- pop ax
- add al,'A'-1 ; make char printable
- tektt4b:call outscrn
- ret
-
- tektt5: cmp bypass,0 ; Bypass mode off?
- jne tektt5a ; ne = no, on, ignore all incoming
- call ttstate ; do current state
- ret
- tektt5a:cmp al,' ' ; incoming control code?
- jae tektt5b ; ae = no
- mov bypass,0 ; turn off bypass
- call ttstate ; act on it
- tektt5b:ret
- tektt endp
-
- TEKTXT proc near ; Dispatch on text characters
- mov ttstate,offset tektxt ; this is our state
- push ax
- call setcursor ; show text cursor
- pop ax
- cmp al,DEL ; RUBOUT?
- jne tektx1 ; ne = no
- mov al,bs ; make BS
- jmp short tektx7
- tektx1: cmp al,CR ; carriage return (^M)?
- je tektx7 ; e = yes
- cmp al,LF ; line feed (^J)?
- je tektx7 ; e = yes
- cmp al,FF ; form feed (^L)?
- jne tektx4 ; ne = no
- call tekcls ; clear the screen
- ret
- tektx4: cmp al,VT ; vertical tab (^K)?
- je tektx7
- cmp al,bell ; bell (^G)?
- jne tektx5 ; ne = no
- call tekbeep
- ret
- tektx5: cmp al,tab ; horizontal tab (^I)?
- je tektx7 ; e = yes
- cmp al,BS ; backspace (^H)?
- je tektx7 ; e = yes
- cmp al,' ' ; control char?
- jae tektx7 ; ae = no
- jmp tekctl ; process control char
- tektx7: call outscrn ; output character to the screen
- tektx8: ret
- TEKTXT endp
-
-
- tekctl proc near ; Control characters:
- cmp al,GS ; Line plot command?
- jne tekctl1 ; ne = no
- mov visible,0 ; next move is invisible
- and status,not txtmode ; set status report byte
- mov ttstate,offset tekline ; expect coordinates next
- call remcursor ; remove text cursor
- ret
- tekctl1:cmp al,RS ; Incremental dot command?
- jne tekctl2 ; ne = no
- and status,not txtmode ; set status report
- mov ttstate,offset tekrlin ; expect pen command next
- call remcursor ; remove text cursor
- ret
- tekctl2:cmp al,FS ; Point plot command?
- jne tekctl3 ; ne = no
- mov visible,0 ; next move is invisible
- and status,not txtmode ; set status report byte
- mov ttstate,offset tekpnt
- call remcursor ; remove text cursor
- ret
- tekctl3:cmp al,US ; assert text mode? [bjh]
- jne tekctl4 ; ne = no
- or status,txtmode ; set status report byte
- mov ttstate,offset tektxt ; go to TEKTXT next time
- mov visible,0 ; next move is invisible
- call setcursor ; restore text cursor
- ret
- tekctl4:cmp al,ESCAPE ; Escape?
- jne tekctl5 ; ne = no
- call remcursor ; remove text cursor
- or status,txtmode ; set status report byte
- cmp ttstate,offset tekesc ; already in escape state?
- je tekctl7 ; e = yes, nest no further
- push ttstate ; current state
- pop prestate ; save here as previous state
- mov ttstate,offset tekesc ; next state parses escapes
- ret
-
- tekctl5:cmp al,CAN ; Control X? (exits Tek sub mode)
- jne tekctl7 ; ne = no, stay in current state
- mov ttstate,offset tektxt ; back to text mode
- mov bypass,1 ; turn on bypass mode
- cmp flags.vtflg,tttek ; main Tek emulator?
- je tekctl6 ; e = yes, ignore the ^X
- call tekend ; else exit sub mode
- and tekflg,not tek_dec ; returning to text emulator
- mov visible,0 ; next move is invisible
- call frepaint ; regenerate text screen
- tekctl6:mov prestate,offset tektxt ; make previous state text
- tekctl7:ret
- tekctl endp
-
- TEKESC proc near ; Process ESC <following text>
- mov ninter,0 ; initialize parsing
- mov ttstate,offset tekesc ; in case get here from msz file
- cmp inited,0 ; inited yet? (msz call)
- jne tekesc1 ; ne = yes
- call tekini ; init now
- mov prestate,offset tektxt ; set a previous state of text
- jnc tekesc1 ; nc = succeeded
- ret ; else failed to init, just return
-
- tekesc1:cmp al,20h ; in intermediates, column 2?
- jb tekesc3 ; b = no
- cmp al,2fh
- ja tekesc3 ; a = no
- mov ttstate,offset tekesc1 ; stay in this state while intermeds
- mov bx,ninter ; number of intermediates
- cmp bx,maxinter ; done enough already?
- jae tekesc2 ; ae = yes, ignore the excess
- mov inter[bx],al ; store this one
- inc ninter ; one more
- cmp inter,'/' ; HDS2000/3000 Final char?
- je tekesc3 ; e = yes, process specially like '['
- tekesc2:ret ; get more input
-
- ; Final char is in AL, dispatch on it
- tekesc3:mov ttstate,offset tektxt ; set new state
- mov esctype,al ; save kind of escape sequence
- mov bx,offset esctab ; ESC dispatch table
- call atdispat ; dispatch on AL
- ret
- TEKESC endp
-
- tekeseq proc near ; process Escape and Device Contrl seq
- call tparstart ; init escape sequence parser
- mov ttstate,offset escparse ; do parsing next
- ret
- tekeseq endp
-
- ; State for gathering text to feed escape sequence parser
- escparse proc near
- cmp al,' ' ; embedded control code?
- jb escpar2 ; b = yes, process now
- call tparser ; far call, to call real parser
- jnc escpar1 ; nc = success
- push prestate ; recover previous state
- pop ttstate
- stc
- escpar1:ret
- escpar2:call tekctl ; process embedded control code
- push prestate ; get previous state
- pop ttstate ; restore it
- ret
- escparse endp
-
- ; Escape sequence parser completion routine
- ; AL has Final character of escape sequence
- XPARDONE PROC FAR ; called by tpardone when done
- cmp esctype,'[' ; ansi escape sequence (ESC [)?
- jne xpardo3 ; ne = no
- mov bx,offset anstab ; ANSI ESC [ table
- call atdispat ; dispatch on Final char in AL
- jmp short xpardo5
-
- xpardo3:cmp esctype,'/' ; HDS escape sequence (ESC /)?
- jne xpardo4 ; ne = no
- call hdsesc ; analyze
- jmp short xpardo5
-
- xpardo4:cmp esctype,'P' ; DCS introducer?
- jne xpardo5 ; ne = no
- call tekdcs ; grab parameters etc, prep strings
- ret
-
- xpardo5:push prestate ; recover previous state
- pop ttstate
- ret
- XPARDONE ENDP
- ; ESC <char> action routines
- ; exit each by putting prestate into ttstate
-
- tekenq proc near ; ESC-^E Enquiry for cursor position
- mov bypass,1 ; set bypass mode
- call sendstat ; send status
- push prestate ; get previous state
- pop ttstate ; restore it
- ret
- tekenq endp
-
- tekcan proc near ; ESC ^X
- push prestate ; get previous state
- pop ttstate ; restore it
- jmp tekctl ; process in controls section
- tekcan endp
-
- tekgin proc near ; ESC-^Z Enter GIN mode
- cmp graph_mode,mono ; Monochrome text mode?
- je tekgin1 ; e = yes, no crosshairs in text mode
- mov bypass,1 ; turn on GIN mode bypass conditon
- call crossini ; preset crosshairs
- tekgin3:call far ptr croshair ; activate the cross-hairs
- jnc tekgin3 ; loop until exit is signaled
- call crossfin ; clean up
- jmp short tekgin2
- tekgin1:call tekbeep ; tell the user we are unhappy
- tekgin2:push prestate ; get previous state
- pop ttstate ; restore it
- ret
- tekgin endp
-
- tektwo proc near ; ESC 2 (Exit Tek mode)
- mov al,CAN ; force Control-X
- jmp tekcan ; process there as ESC ^X
- tektwo endp
-
- tekqury proc near ; query mark (ESC ? means DEL)
- mov al,DEL ; replace with DEL code
- push prestate ; get previous state
- pop ttstate ; restore it
- ret
- tekqury endp
-
- tekfill proc near ; Fill series ESC @ .. ESC M
- sub al,'@' ; remove bias
- mov bl,al
- xor bh,bh
- shl bx,1 ; make a word index
- mov bx,fillist[bx] ; get pointer to the pattern from list
- mov fillptr,bx ; assign this pattern pointer
- push prestate ; get previous state
- pop ttstate ; restore it
- ret
- tekfill endp
-
- teklpat proc near ; ESC accent grave line pattern series
- cmp al,'g' ; accent ... lowercase g?
- jbe teklpa2 ; be = yes
- cmp al,'o' ; bold patterns ESC h..ESC o?
- ja teklpa1 ; a = no
- sub al,'h'-accent ; map bold to normal
- jmp short teklpa2
- teklpa1:sub al,'x'-'f' ; user sets,map x to f, y to g, z to h
- teklpa2:push bx
- mov bl,al
- sub bl,accent ; remove bias
- cmp bl,8 ; nine patterns, ignore others
- jbe teklpa3 ; be = ok, make others accent, solid
- xor bl,bl ; solid pattern
- teklpa3:xor bh,bh
- shl bx,1 ; make this a word index
- mov bx,linetab[bx] ; get line pattern word
- mov linepat,bx ; save in active word
- pop bx ; return to previous mode
- push prestate ; get previous state
- pop ttstate ; restore it
- ret
- teklpat endp
-
- ; Detect exit Tek submode command ESC [ ? 38 l from VT340's
- escexit proc near
- cmp lparam,'?' ; possible "ESC [ ? 38 l"?
- jne escex2 ; ne = no
- cmp nparam,1 ; just one numeric parameter?
- jne escex2 ; ne = no
- cmp al,'l' ; ESC [ ? Pn l?
- jne escex2 ; ne = no
- cmp param,38 ; correct value?
- jne escex2 ; ne = no
- cmp flags.vtflg,tttek ; are we a full Tek terminal now?
- je escex1 ; e = yes, stay that way
- call far ptr tekend
- and tekflg,not tek_dec ; returning to text emulator
- call frepaint
- ret
- escex1: mov ttstate,offset tektxt
- mov al,CAN ; simulate arrival of Control-X
- jmp tektxt ; process char as text
- escex2: ret
- escexit endp
-
- ; Human Data Systems 2000/3000 style escape sequences (ESC / params Final)
- ; Final character is in AL
- hdsesc proc near
- cmp al,'x' ; draw an empty rectangle?
- jne hdsesc0 ; ne = no
- call rectdraw
- jmp short hdsesc2a
- hdsesc0:cmp al,'y' ; draw a filled rectangle?
- jne hdsesc1 ; ne = no
- call rectfil ;do xhome,yhome,xwidth,yheight,pattern
- jmp short hdsesc2a
- hdsesc1:cmp al,'z' ; draw and fill rectangle?
- jne hdsesc2 ; ne = no
- call rectfil ; do fill before border
- call rectdraw ; do border
- jmp short hdsesc2a
- hdsesc2:cmp ninter,0 ; any intermediates?
- jne hdsesc2a ; ne = yes, failure
- cmp lparam,0 ; letter parameter?
- jne hdsesc2a ; ne = yes, failure
- cmp nparam,1 ; just zero or one numeric parameter?
- ja hdsesc9 ; a = no
- cmp al,'a' ; user defined pattern?
- jb hdsesc3 ; b = no
- cmp al,'c'
- ja hdsesc3 ; a = no
- sub al,'a' ; 'a' is first of three user patterns
- xor ah,ah ; store as 'f,g,h' in the series
- mov bx,ax
- shl bx,1 ; make a word index
- mov ax,param[0] ; get the 16-bit pattern
- mov linetab[bx+12],ax ; store in user defined pattern
- hdsesc2a:push prestate ; get previous state
- pop ttstate ; restore it
- ret
-
- hdsesc3:cmp al,'d' ; "Data Level" (pixel ops)?
- jne hdsesc4 ; ne = no
- mov cx,param ; get the parameter value
- mov al,pixfor ; assume foreground only ESC / 0 d
- cmp cl,1 ; something else?
- jb hdsesc3a ; b = no
- mov al,pixbak ; assume background only ESC / 1 d
- cmp cl,2 ; something else?
- jb hdsesc3a ; b = no
- mov al,pixxor ; assume XOR ESC / 2 d
- cmp cl,3 ; something else?
- jb hdsesc3a ; b = no
- ja hdsesc3b ; a = unknown, ignore
- mov al,pixfor+pixbak ; write both absolute ESC / 3 d
- hdsesc3a:mov ccode,al ; use as pixel op coding
- hdsesc3b:push prestate ; get previous state
- pop ttstate ; restore it
- ret
-
- hdsesc4:cmp al,'h' ; set space, backspace control?
- je hdsesc4a ; e = yes
- cmp al,'l' ; reset space, backspace control?
- jne hdsesc9 ; ne = no
- xor ah,ah ; say resetting
- jmp short hdsesc5
- hdsesc4a:mov ah,1 ; say setting
- hdsesc5:cmp param,2 ; space control?
- jne hdsesc5a ; ne = no
- mov spcontrol,ah ; reset (0) or set destructive SPACE
- push prestate ; get previous state
- pop ttstate ; restore it
- ret
- hdsesc5a:cmp param,9 ; destructive backspace?
- jne hdsesc13 ; ne = no
- mov bscontrol,ah ; reset (0) or set destructive BS
-
- hdsesc9:cmp al,'C' ; user defined fill pattern #1?
- jne hdsesc10 ; ne = no
- mov di,offset filpat13 ; storage area for user pattern #1
- jmp short hdsesc11
- hdsesc10:cmp al,'D' ; user defined fill pattern #2?
- jne hdsesc11 ; ne = no
- mov di,offset filpat14 ; storage area for user pattern #2
- hdsesc11:mov cx,8 ; do 8 paramters
- xor bx,bx
- hdsesc12:mov ax,param[bx] ; copy 8 bit fill pattern
- mov [di],al ; to array
- add bx,2
- inc di
- loop hdsesc12
- hdsesc13:push prestate ; get previous state
- pop ttstate ; restore it
- ret
- hdsesc endp
-
- ; Analyze ESC [ Pn ; Pn m color command
- ; where Pn = 30-37 foreground color, 40-47 background color, ANSI standard
- ; Enter with escape sequence already parsed.
- TEKCOL proc near
- push si
- cld
- mov al,gfcol ; update these in case error
- mov tfcol,al
- mov al,gbcol
- mov tbcol,al
- mov si,offset param ; parameters from parser
- mov cx,nparam ; number of parameters
- tekco1: jcxz tekco5 ; z = none left
- lodsw ; parameter to ax
- dec cx
- or ax,ax ; 0, remove intensity, set b/w?
- jnz tekco2 ; nz = no
- mov tfcol,7 ; regular white
- mov tbcol,0 ; on black
- jmp short tekco1
-
- tekco2: cmp ax,1 ; intensity bit?
- jne tekco3 ; ne = no
- or tfcol,8 ; set foreground intensity
- jmp short tekco1
-
- tekco3: cmp ax,30 ; foreground series?
- jb tekco1 ; b = no
- cmp ax,37
- ja tekco4 ; a = no
- sub ax,30 ; remove bias
- push bx
- mov bl,al
- xor bh,bh
- mov al,byte ptr colortb[bx] ; reverse coloring
- pop bx
- and tfcol,not (7) ; retain intensity bit
- or tfcol,al ; remember foreground color
- jmp short tekco1
-
- tekco4: cmp ax,40
- jb tekco1
- cmp ax,47 ; legal value?
- ja tekco1 ; a = no
- sub al,40
- push bx
- mov bl,al
- xor bh,bh
- mov al,byte ptr colortb[bx] ; reverse coloring
- pop bx
- mov tbcol,al ; remember background color
- jmp short tekco1
-
- tekco5: cmp ninter,0 ; intermediates?
- jne tekco7 ; ne = yes, no go
- cmp lparam,0 ; letter parameter?
- jne tekco7 ; ne = yes, no go
- cmp nparam,0 ; number of ansi arguments, zero?
- ja tekco6 ; a = no, got some
- mov tbcol,0 ; none is same as 0, set b/w
- mov tfcol,7
- tekco6: mov al,tbcol ; success, store coloring
- mov gbcol,al ; set background color
- mov al,tfcol
- mov gfcol,al ; set foreground color
- call fixcolor ; do special ega corrections
- mov al,gfcol ; update these in case error
- mov tfcol,al
- mov colpal[7],al ; foreground goes here
- mov al,gbcol
- mov tbcol,al
- mov colpal[0],al ; background goes here
- tekco7: pop si
- clc
- ret
- TEKCOL endp
-
- ; Revise screen color codes for ega boards with mono displays and limited
- ; memory.
- fixcolor proc near
- cmp graph_mode,ega ; one of these ega modes?
- je fixcol6 ; e = yes
- cmp graph_mode,colorega
- je fixcol6
- cmp graph_mode,monoega
- je fixcol6
- cmp plotptr,offset pltcga ; using CGA style graphics?
- jne fixcol5 ; ne = no
- and gfcol,7 ; strip intensity
- jmp short fixcol6 ; keep colors different
- fixcol5:ret ; else ignore color corrections
- fixcol6:mov ah,gfcol
- mov al,gbcol
- cmp plotptr,offset pltcga ; CGA style?
- jne fixcol8 ; ne = no
- or ah,ah ; bright foreground?
- jnz fixcol7 ; nz = yes
- mov al,1 ; make background illuminated
- jmp short fixcol3
- fixcol7:xor al,al ; force background to dark
- fixcol8:cmp graph_mode,monoega ; monochrome ega display?
- jne fixcol3 ; ne = no
- test al,7 ; bright backgound?
- jnz fixcol1 ; nz = yes
- mov ah,1 ; normal foreground
- test gfcol,8 ; intensity on?
- jz fixcol1 ; z = no
- mov ah,5 ; say bright foreground
- fixcol1:test al,7 ; black backgound?
- jz fixcol2 ; z = yes
- mov al,1 ; regular video
- fixcol2:cmp ah,al ; same color in both?
- jne fixcol3 ; ne = no
- mov ah,1 ; make foreground regular
- xor al,al ; and background black
- fixcol3:mov gfcol,ah
- mov gbcol,al
- cmp gpage,0 ; minimal memory (64KB mono and ega)?
- ja fixcol4 ; a = no, enough, else strange mapping
- mov al,gfcol ; fix coloring to map planes C0 to C1
- and al,5 ; and C2 to C3 (as 0, 3, 0Ch, or 0Fh)
- mov ah,al ; make a copy
- shl ah,1 ; duplicate planes C0, C2 in C1, C3
- or al,ah ; merge the bits
- mov gfcol,al ; store proper foreground color
- mov al,gbcol ; repeat for background color
- and al,5
- mov ah,al
- shl ah,1
- or al,ah
- mov gbcol,al
- fixcol4:ret
- fixcolor endp
-
- tekrid proc near ; report Tek screen parameters
- cmp lparam,'?' ; possible "ESC [ ? 38 l"?
- jne tekridx ; ne = no
- cmp nparam,1 ; just one numeric parameter?
- jne tekridx ; ne = no
- cmp param,256 ; correct value?
- je tekrid1 ; e = yes
- tekridx:ret
- tekrid1:push es ; as ESC [ ? 256; height; len; #col n
- push ds
- pop es
- cld
- mov di,offset rdbuf ; a temp buffer
- mov al,escape ; report
- stosb
- mov al,'['
- stosb
- mov al,'?'
- stosb
- mov ax,256
- call dec2di ; write ascii digits
- mov al,';'
- stosb
- mov ax,ybot ; do height
- inc ax
- cmp graph_mode,mono ; pure mono text system?
- jne tekrid7a ; ne = no
- mov ax,24
- tekrid7a:call dec2di
- mov al,';' ; separator
- stosb
- mov ax,xmax ; width
- add ax,8 ; in dots
- cmp graph_mode,mono ; pure mono text system?
- jne tekrid7b ; ne = no
- mov ax,80
- tekrid7b:call dec2di
- mov al,';' ; separator
- stosb
- mov al,'1' ; screen colors, assume 1
- stosb
- cmp plotptr,offset pltcga ; using CGA style graphics?
- je tekrid4 ; e = yes
- cmp graph_mode,monoega ; monochrome monitor on ega?
- je tekrid4 ; e = yes
- cmp graph_mode,mono ; pure mono text system?
- jne tekrid3
- mov byte ptr [di-1],'0' ; say zero colors
- jmp short tekrid4
- tekrid3:mov al,'6'
- stosb ; say 16
- tekrid4:mov al,'n' ; end of string
- stosb
- call outstrng ; send the string
- pop es
- ret
- tekrid endp
-
- tekprpt proc near
- cmp nparam,1 ; one or more numeric parameters?
- jb tekrprx ; b = no
- cmp param,2 ; "CSI 2 $ u"?
- jne tekrprx ; ne = no
- cmp inter,'$' ; correct Intermediate?
- jne tekrprx ; ne = no
- call far ptr tekrpt ; invoke the palette report generator
- tekrprx:ret
- tekprpt endp
-
- tekrpt proc FAR ; report VT340 color palette
- push es ; DECRQTSR(request), DECCTR(response)
- push ds
- pop es
- push di
- push bx
- cld
- mov di,offset rdbuf ; a temp buffer
- mov al,escape ; report
- stosb
- cmp plotptr,offset pltcga ; using CGA style graphics?
- je tekrpt9 ; e = yes
- cmp graph_mode,mono ; pure mono text system?
- je tekrpt9 ; e = yes
- cmp graph_mode,monoega ; monochrome monitor on ega?
- jne tekrpt10 ; ne = no
- tekrpt9:mov ax,'0P' ; b/w systems report DCS 0 $ s ST
- stosw
- mov ax,'s$'
- stosw
- call outstrng
- jmp tekrpt8
-
- tekrpt10:mov ax,'2P' ; color systems report DCS 2 $ s...ST
- stosw
- mov ax,'s$'
- stosw ; "ESC [ 2 $ s"
- call outstrng ; output this string
- mov cx,16 ; number of palette registers to do
- xor bx,bx ; begin with color palette 0
- tekrpt1:push bx ; save palette index
- push cx ; save loop counter
- mov di,offset rdbuf ; buffer
- mov ax,bx ; palette number
- call dec2di ; palette register, to buffer
- mov ax,'2;' ; ";2;" means sending RGB values
- stosw
- mov al,';'
- stosb
- mov ah,colpal[bx] ; get palette iRGB
- mov al,rgbbold/4 ; assume dark red for bold black
- cmp ah,8 ; bold black?
- je tekrpt2 ; e = yes
- xor al,al
- test ah,4 ; red?
- jz tekrpt2 ; z = no
- mov al,rgbbold/2 ; say red, 40%
- test ah,8 ; bold?
- jz tekrpt2 ; z = no
- mov al,rgbbold ; more if bold
- tekrpt2:push ax
- xor ah,ah ; clear high byte
- call dec2di ; store red
- pop ax
- mov al,';' ; separator
- stosb
- mov al,rgbbold/4 ; assume dark green for bold black
- cmp ah,8 ; bold black?
- je tekrpt4 ; e = yes
- xor al,al
- test ah,2 ; green?
- jz tekrpt4 ; z = no
- mov al,rgbbold/2 ; say green, 40%
- test ah,8 ; bold?
- jz tekrpt4 ; z = no
- mov al,rgbbold ; more if bold
- tekrpt4:push ax
- xor ah,ah ; clear high byte
- call dec2di ; store green
- pop ax
- mov al,';' ; separator
- stosb
- mov al,rgbbold/4 ; assume dark blue for bold black
- cmp ah,8 ; bold black?
- je tekrpt6 ; e = yes
- xor al,al
- test ah,1 ; blue?
- jz tekrpt6 ; z = no
- mov al,rgbbold/2 ; say blue, 40%
- test ah,8 ; bold?
- jz tekrpt6 ; z = no
- mov al,rgbbold ; more if bold
- tekrpt6:xor ah,ah ; clear high byte
- call dec2di ; store blue
- pop cx ; recover loop counter
- cmp cx,1 ; doing last item?
- je tekrpt7 ; e = yes, do not send another "/"
- mov al,'/' ; separator
- stosb
- tekrpt7:push cx
- call outstrng ; output this string
- pop cx
- pop bx ; recover palette index
- inc bx ; ready for next palette
- dec cx
- jz tekrpt8 ; z = done
- jmp tekrpt1 ; do all palettes
- tekrpt8:mov al,escape ; DCS terminator ST
- call outmodem
- mov al,'\'
- call outmodem
- pop bx
- pop di
- pop es
- ret
- tekrpt endp
-
- ; Output string in rdbuf. Enter with di pointing at last byte+1. Return
- ; with di at the same place.
- outstrng proc near
- mov ttyact,0 ; group output for network
- push cx
- mov cx,di ; compute length
- mov di,offset rdbuf ; start of buffer
- sub cx,di ; start of buffer
- jle outstn3 ; le = nothing to do
- outstn1:mov al,[di]
- inc di
- cmp cx,1 ; last character?
- ja outstn2 ; a = no
- mov ttyact,1 ; end group output for network
- outstn2:call outmodem ; send the byte
- loop outstn1 ; do the string
- outstn3:pop cx
- ret
- outstrng endp
-
- ; Process Device Control Strings (DCS or ESC P lead-in chars, parameters,
- ; and Final character already read). Prepare to gather strings.
- tekdcs proc near
- mov dcsstrf,al ; record Final char
- mov emubufc,0 ; clear string count
- mov cx,maxparam ; number of DCS parameters
- push si ; copy these to the DCS area so that
- push di ; they are not lost when an ST is
- push es ; parsed (parser clears ESC items)
- push ds
- pop es
- mov si,offset param ; ESC paramater storage area, numeric
- mov di,offset dparam ; DCS parameter storage area, numeric
- cld
- rep movsw ; copy set to DCS storage area
- mov cl,lparam ; copy letter Paramter
- mov dlparam,cl
- mov cx,maxinter ; number of intermediate characters
- mov si,offset inter ; source
- mov di,offset dinter ; destination
- rep movsb
- mov si,nparam ; number of parameters
- mov dnparam,si
- mov si,ninter
- mov dninter,si ; number of intermediates
- pop es
- pop di
- pop si
- cmp dcsstrf,'q' ; Sixel Graphics?
- jne tekdcs3 ; ne = no
- mov ttstate,offset tekgets ; get string as next state
- mov al,chcontrol ; opaque/transparent char writing
- or al,al ; is it being set?
- jz tekdcs2 ; z = no, do not force condition
- mov bscontrol,al ; set destructive BS control
- mov spcontrol,al ; set destructive SPACE control
- tekdcs2:ret
- tekdcs3:cmp dcsstrf,'p' ; restore color palette (DCS 2 $ p)?
- jne tekdcs1 ; ne = no
- cmp nparam,1 ; just one parameter?
- jne tekdcs1 ; ne = no
- cmp param,2 ; correct parameter?
- jne tekdcs1 ; ne = no
- cmp dinter,'$' ; correct intermediate?
- jne tekdcs1 ; ne = no
- mov ttstate,offset tekrcol ; get color report as next state
- ret
- tekdcs1:mov ttstate,offset tekdcsnul ; consume unknown DCS
- ret
- tekdcs endp
-
- ; Read and discard OSC (ESC ]), PM (ESC ^), APC (ESC _) control sequences
- ; through final ST (ESC \) terminator.
- tekdcsnul proc near
- mov dcsstrf,0 ; simulate a null (dummy) Final char
- cmp al,20h ; control char?
- jae tekdcsnu1 ; ae = no, skip
- jmp tekctl ; do control char
- tekdcsnu1:ret
- tekdcsnul endp
-
- ; State machine to process DCS strings of type "p" (restore color palette)
- ; Enter with "p" char in AL. Callable from outside this file via tekrpal.
- tekrcol proc near
- mov ttstate,offset tekrco1 ; next state is get parameter
- push ax ; save character
- push es
- push ds
- pop es
- push di
- mov cx,5 ; five words
- xor ax,ax
- mov di,offset param ; clear parameters Pc,Pu,Px,Py,Pz
- cld
- rep stosw
- pop di
- pop es
- mov nparam,0 ; work on initial parameter first
- pop ax
- tekrco1:cmp al,escape ; escape, as in ESC \?
- je tekrcost ; e = yes, finish command
- cmp al,' ' ; control code?
- jb tekrco5 ; b = yes, ignore it
- push bx
- mov bx,nparam ; parameter number
- shl bx,1 ; make it a word index
- mov cx,param[bx] ; accumulated parameter
- call getdec ; accumulate decimal value
- mov param[bx],cx ; remember accumulation
- pop bx
- jnc tekrco5 ; nc = got a digit char
- inc nparam ; say have another complete parameter
- cmp al,'/' ; this kind of separator?
- je tekrco3 ; e = yes, finish
- cmp al,';' ; break char is separator?
- jne tekrco4 ; ne = no, decode current sequence
- tekrco3:cmp nparam,5 ; have 5 params already?
- jb tekrco5 ; n = no, continue reading
- tekrco4:call tekgco4 ; process parameters in msgibm file
- mov ttstate,offset tekrcol ; next state is get parameter
- tekrco5:ret ; start over on next field
-
- tekrcost: ; get here on ST
- cmp nparam,5 ; enough parameters to finish cmd?
- jb tekrcos1 ; b = no, abandon it
- call tekgco4 ; update from last data item
- mov al,escape
- tekrcos1:jmp tekctl
- tekrcol endp
-
- ; State machine to process DCS strings of type "q" (Sixel Command and Data)
- ; Enter with new char in AL.
- tekgets proc near
- mov ttstate,offset tekgets ; set state to ourselves
- mov nparam,0 ; say no pending control sequences
- cmp al,20h ; control character?
- jae tekgsch ; ae = no, analyze
- jmp tekctl ; do control char
- ; single sixel char state
- tekgsch:cmp al,3fh ; legal sixel data char?
- jb tekgrpt ; b = no, try repeated char
- mov cx,1 ; repeat count of 1
- jmp sixplt ; plot the six dots
-
- tekgrpt:cmp al,'!' ; repeated char?
- jne tekgera ; ne = no
- mov ttstate,offset tekgrpt0 ; next state is get repeat parameter
- mov param,0
- mov nparam,0
- ret
-
- tekgrpt0:cmp al,' ' ; control char?
- jae tekgrpt1 ; ae = no
- jmp tekctl ; process control char
- tekgrpt1:mov cx,param ; first param is used here
- call getdec ; accumulate repeat count to cx
- mov param,cx ; retain current count
- jc tekgrpt2 ; c = ended on non-numeric
- ret ; get more characters
- tekgrpt2:cmp al,3fh ; break char, is it a sixel datum?
- jb tekgrpt3 ; b = no, it is illegal, quit
- call sixplt ; plot cx versions of the six bits
- mov ttstate,offset tekgets ; return to sixel idle state
- ret
- tekgrpt3:jmp short tekgets ; reprocess break character
-
- tekgera:cmp al,22h ; double quote raster attribute?
- jne tekgco ; ne = no, try color
- mov param,0 ; clear parameters, Pan
- mov param[2],0 ; Pad
- mov param[4],0 ; Ph
- mov param[6],0 ; Pv
- mov nparam,0 ; work on initial parameter first
- mov ttstate,offset tekgra1 ; next state is get parameter
- ret
- tekgra1:cmp al,' ' ; control char?
- jb tekgra2 ; b = yes, finish this work first
- push bx
- mov bx,nparam ; parameter number
- shl bx,1 ; make it a word index
- mov cx,param[bx] ; accumulated parameter
- call getdec ; accumulate decimal value into cx
- mov param[bx],cx ; remember accumulation
- pop bx
- jc tekgra2 ; c = failure to get a digit char
- ret
- tekgra2:inc nparam ; say have another complete parameter
- cmp nparam,4 ; got all four params Pan,Pad,Ph,Pv?
- je tekgra4 ; e = yes
- cmp al,';' ; break char is separator?
- jne tekgra3 ; ne = no, quit now
- ret ; get more characters
- tekgra3:jmp tekgets ; restart with the break char
-
- tekgra4:;;; perform raster attributes work here
- mov ttstate,offset tekgets
- ret
-
- tekgco: cmp al,'#' ; color introducer?
- je tekgco0 ; e = yes
- jmp tekgcr ; ne = no
- tekgco0:mov ttstate,offset tekgco1 ; next state is get parameter
- push ds
- pop es
- push di
- mov cx,5 ; five words
- xor ax,ax
- mov di,offset param ; clear parameters Pc,Pu,Px,Py,Pz
- cld
- rep stosw
- pop di
- pop es
- mov nparam,0 ; work on initial parameter first
- ret
- tekgco1:cmp al,' ' ; control char?
- jb tekgco2 ; b = yes, finish this work first
- push bx
- mov bx,nparam ; parameter number
- shl bx,1 ; make it a word index
- mov cx,param[bx] ; accumulated parameter
- call getdec ; accumulate decimal value
- mov param[bx],cx ; remember accumulation
- pop bx
- jc tekgco2 ; c = failure to get a digit char
- ret
- tekgco2:inc nparam ; say have another complete parameter
- cmp al,';' ; break char is separator?
- jne tekgco3 ; ne = no, decode current sequence
- cmp nparam,5 ; have 5 params already?
- jae tekgco3 ; ae = yes, process them now
- ret ; else get more parameters
- tekgco3:cmp nparam,1 ; just one parameter?
- je tekgco3a ; e = yes, select from palette
- jb tekgco3b ; b = none, reprocess as sixel
- call tekgco4 ; process parameters
- mov nparam,0 ; clear parameters
- jmp tekgets ; reprocess char as sixel
-
- tekgco3a:push bx ; select color from palette
- mov bx,param[0] ; get color number
- xor bh,bh ; make 0-255
- mov bl,colpal[bx] ; get color from palette
- mov gfcol,bl ; set active foreground color
- pop bx
- push ax ; save char in al
- call fixcolor ; fix color too, if req'd
- pop ax
- tekgco3b:mov nparam,0 ; clear parameters
- jmp tekgets ; reprocess char as sixel
-
- ; set IRGB/HLS color to color palette
- tekgco4:cmp param[2],2 ; Pu (1-2), wanted RBG?
- je tekgco4b ; e = yes
- cmp param[2],1 ; Pu, wanted HLS?
- jne tekgco4a ; ne = no
- jmp tekgco9 ; do HLS scheme
- tekgco4a:mov nparam,0 ; clear parameters
- ret ; return without doing work
- tekgco4b:push ax ; iRGB, save break char in al
- mov ax,param[4] ; red
- mov bx,param[6] ; green
- mov dx,param[8] ; blue
- xor cx,cx ; cl has final color index, 0-15
- or ch,al
- or ch,bl
- or ch,dl ; any color?
- jcxz tekgco7 ; z = no, use cl = 0 black
- cmp ax,rgbbold ; setting red bold?
- jae tekgco4c ; ae = yes
- cmp bx,rgbbold ; setting green bold?
- jae tekgco4c ; ae = yes
- cmp dx,rgbbold ; setting blue bold?
- jb tekgco4d ; b = no
- tekgco4c:mov cl,8 ; set the bold bit
- jmp tekgco4e ; do hues
- tekgco4d:cmp ax,rgbbold/2 ; all in dim intensities?
- jae tekgco4e ; ae = no
- cmp bx,rgbbold/2 ; green?
- jae tekgco4e ; ae = no
- cmp dx,rgbbold/2 ; blue
- jae tekgco4e ; ae = no
- mov cl,8 ; use bold black (dark grey)
- jmp tekgco7
- tekgco4e:or ax,ax ; Hues, any red?
- jz tekgco5 ; z = no
- or cl,4 ; set red bit
- cmp ax,rgbbold/2 ; dim?
- jae tekgco5 ; ae = no
- test cl,8 ; doing bold?
- jz tekgco5 ; z = no
- xor cl,4 ; clear dim red
- tekgco5:or bx,bx ; any green?
- jz tekgco6 ; z = no
- or cl,2 ; set green bit
- cmp bx,rgbbold/2 ; dim?
- jae tekgco6 ; ae = no
- test cl,8 ; doing bold?
- jz tekgco6 ; z = no
- xor cl,2 ; clear dim green
- tekgco6:or dx,dx ; any blue?
- jz tekgco7 ; z = no
- or cl,1 ; set blue bit
- cmp dx,rgbbold/2 ; dim?
- jae tekgco7 ; ae = no
- test cl,8 ; doing bold?
- jz tekgco7 ; z = no
- xor cl,1 ; clear dim blue
- tekgco7:push bx
- mov bx,param[0] ; Pc, color palette being defined
- xor bh,bh ; make 0-255
- mov colpal[bx],cl ; store color code in palette
- pop bx
- mov nparam,0 ; say done with this sequence
- pop ax ; recover break char in al
- ret
-
- ; Hue, Lightness, Saturation
- tekgco9:push ax ; save break char
- xor cl,cl ; assummed color of black
- mov ax,param[4] ; Px, Hue, 60 degree slices
- push cx
- mov cx,360 ; do modulo 360
- xor dx,dx ; clear high order numerator
- div cx ; dx has remainder
- pop cx
- mov ax,dx ; put remainder in ax
- cmp ax,30 ; blue?
- jae tekgco10 ; ae = no
- or cl,1 ; blue
- jmp short tekgco15
- tekgco10:cmp ax,90 ; magenta?
- jae tekgco11 ; ae = no
- or cl,1+4 ; magenta = blue + red
- jmp short tekgco15
- tekgco11:cmp ax,150 ; red?
- jae tekgco12 ; ae = no
- or cl,4 ; red
- jmp short tekgco15
- tekgco12:cmp ax,210 ; yellow?
- jae tekgco13 ; ae = no
- or cl,4+2 ; yellow = reg + green
- jmp short tekgco15
- tekgco13:cmp ax,270 ; cyan?
- jae tekgco14 ; ae = no
- or cl,2+1 ; cyan = green+blue
- jmp short tekgco15
- tekgco14:or cl,1 ; blue
-
- tekgco15:mov ax,param[6] ; Py, Lightness
- mov dx,param[8] ; Pz, Saturation
- cmp ax,86 ; lightness is max?
- jb tekgco16 ; b = no
- mov cl,0fh ; greater than 85% means bold white
- jmp short tekgco22
- tekgco16:cmp ax,71 ; high lightness?
- jb tekgco17 ; b = not that light
- or cl,8 ; turn on bold bit
- cmp dx,51 ; saturated?
- jae tekgco22 ; ae = yes
- mov cl,0fh ; low saturation yields bold white
- jmp short tekgco22
- tekgco17:cmp ax,57 ; central coloring, upper?
- jb tekgco18 ; b = no
- or cl,8 ; turn on bold bit
- cmp dx,51 ; saturated?
- jae tekgco22 ; ae = yes, use bold colors
- mov cl,7 ; s < 50 is dim white
- cmp dx,11 ; saturated less than 11%
- jae tekgco22 ; ae = no
- xor cl,cl ; s < 11 is black here
- jmp short tekgco22
- tekgco18:cmp ax,43 ; dim colors, upper?
- jb tekgco19 ; b = no
- or cl,8 ; turn on bold bit
- cmp dx,51 ; saturated?
- jae tekgco22 ; ae = yes, use bold colors
- and cl,not 8 ; use dim colors
- jmp short tekgco22
- tekgco19:cmp ax,29 ; dim colors, lower?
- jb tekgco20 ; b = no
- cmp dx,51 ; saturated?
- jae tekgco22 ; ae = yes
- mov cl,7 ; use dim white
- jmp short tekgco22
- tekgco20:cmp ax,14 ; dark colors?
- jb tekgco21 ; b = no
- cmp dx,51 ; saturated?
- jae tekgco22 ; ae = yes
- tekgco21:xor cl,cl ; use black
- tekgco22:push bx
- mov bx,param[0] ; Pc, color palette being defined
- xor bh,bh ; get palette 0-255
- mov colpal[bx],cl ; store color code in palette
- pop bx
- mov nparam,0 ; say done with this sequence
- pop ax ; recover break char
- ret
-
- tekgcr: cmp al,'$' ; graphics carriage return?
- jne tekgnl ; ne = no
- mov x_coord,0 ; go to left margin, no line feed
- ret
- tekgnl: cmp al,'-' ; graphics new line?
- jne tekgunk ; ne = no
- mov x_coord,0 ; go to left margin, no line feed
- mov ax,y_coord ; bottom of char cell
- add ax,6 ; go down 6 dots
- cmp ax,ybot ; wrapping below bottom?
- jbe tekgnl1 ; be = no
- mov ax,ybot ; stop at bottom (leaves 2 dots free!)
- tekgnl1:mov y_coord,ax
- ret
- tekgunk:mov ttstate,offset tekgets ; unknown char
- cmp al,' ' ; control char?
- jae tekgun1 ; ae = no
- jmp tektxt ; process control char
- tekgun1:ret ; ignore the unknown char
- tekgets endp
-
- ; Accumulate decimal value in CX using ascii char in al.
- ; Return with value in CX. Return carry clear if ended on a digit,
- ; return carry set and ascii char in al if ended on a non-digit.
- getdec proc near
- cmp al,'0' ; a number?
- jb getdecx ; b = no, quit
- cmp al,'9'
- ja getdecx ; a = not a number, quit
- sub al,'0' ; remove ascii bias
- xchg cx,ax ; put char in cx, decimal value in ax
- push dx ; save reg
- mul ten ; times ten for a new digit
- pop dx ; recover reg, ignore overflow
- add al,cl ; add current digit
- adc ah,0 ; 16 bits worth
- xchg ax,cx ; rpt cnt back to cx
- clc ; say found a digit
- ret
- getdecx:stc ; say non-digit (in al)
- ret
- getdec endp
-
- ; Display lower six bits of AL in a column, a sixel datum. Do CX times.
- ; Location is PC text cursor, x_coord, y_coord, with least significant bit
- ; at the top (at y_coord-8). Increments x_coord by one for each interation
- ; but stops at right margin and does not change y_coord. If dparam[2], P2,
- ; is 1 then color pattern 0 bits in current background, else skip them.
- sixplt proc near
- or cx,cx ; repeat count present?
- jnz sixplt1 ; nz = yes
- ret
- sixplt1:push ax
- push bx
- push linepat ; save line pattern
- sub al,3fh ; remove ascii bias from sixel char
- xor ah,ah
- mov linepat,ax ; our dot pattern in lower 6 bits
- mov di,y_coord ; text bottom cell line
- sub di,charhgt ; go to top of charhgt high char cell
- jnc sixplt2 ; nc = no wrap over top
- xor di,di ; limit to screen top
- sixplt2:mov bx,di ; bx = ending y
- add bx,5 ; plus our six dots (goes down screen)
- cmp bx,ybot ; wrapping below bottom?
- jbe sixplt3 ; be = no
- mov bx,ybot ; stop at bottom
- sixplt3:mov ax,x_coord ; left edge of text cell
- mov si,ax ; si=starting, ax=ending PC x coord
- add xmax,7 ; refer to right edge, not right char
- push es ; set up for dot plotting, save regs
- push si
- push di
- push dx
- push bp
- mov dl,ccode ; existing pixel op code
- push dx ; save ccode around line drawing
- mov ccode,pixor ; set OR pixel op for use by plot()
- cmp gfcol,0 ; all black dots?
- jne sixplt3a ; ne = no
- mov ccode,pixfor ; yes, force overwriting to nulls
- sixplt3a:push cx
- call psetup ; setup display and es:di and es:si
- pop cx
- ; start sixel repeat loop
- sixplt4:push cx ; save sixel repeat count
- push di ; save y starting screen address
- mov bp,linepat ; store active line pattern word in BP
- mov cx,6 ; six dots per sixel
- ; start six dot loop
- sixplt5:push cx ; save dot count
- mov cl,pixFor ; assume foreground coloring
- ;;;; test bp,1 ; bit to be plotted, is it a 1?
- ;;;; jnz sixplt6 ; nz = yes, plot in foreground color
- ;;;; cmp dparam[2],1 ; P2 = 1, skip over 0's?
- ;;;; je sixplt6 ; e = yes
- ;;;; mov cl,pixbak ; use background write pixel op
- ;;;; or bp,1 ; set pattern bit so we see a pixel
- sixplt6:mov ccode,cl ; desired pixel op
- call plotptr ; plot a dot if it is a 1
- call pincy ; next dot down the screen (di)
- pop cx ; recover dot counter
- loop sixplt5 ; do each of 6 dots
- ;
- pop di ; recover starting y screen coord
- pop cx ; recover repeat count
- cmp ax,xmax ; off right edge?
- jae sixplt8 ; ae = yes
- inc ax ; move right one pixel
- inc si ; start and stop x's
- sixplt8:loop sixplt4 ; repeat sixel cx times
- pop dx
- mov ccode,dl ; recover main color code
- pop bp
- pop dx
- pop di
- pop si
- pop es
- mov x_coord,ax ; new text starting x coord
- sub xmax,7 ; restore to right most char cell
- pop linepat ; restore normal line pattern
- pop bx
- pop ax
- ret
- sixplt endp
-
- ; Process ST or ESC \ String Terminator.
- tekgotst proc near
- mov dcsstrf,0 ; clear DCS Final char
- mov nparam,0
- mov ninter,0
- mov al,colpal[7] ; reset foreground to palette 7
- mov gfcol,al
- mov al,colpal[0] ; and background to palette 0
- mov gbcol,al
- call fixcolor ; and fix up coloring, if req'd
- mov prestate,offset tektxt ; reset state of emulator to normal
- mov ttstate,offset tektxt
- call setcursor ; restore text cursor
- ret
- tekgotst endp
-
- TEKLINE proc near ; GS line drawing
- cmp al,' ' ; control char?
- jae teklin3 ; ae = no
- cmp al,CR ; exit drawing on CR,LF,RS,US,FS,CAN
- je teklin2 ; e = yes, a cr
- cmp al,LF ; these terminate line drawing cmds
- je teklin2
- cmp al,FS ; <FS>
- je teklin2
- cmp al,GS ; <GS>
- je teklin2
- cmp al,RS ; <RS>
- je teklin2
- cmp al,US ; <US>
- je teklin2
- cmp al,CAN ; and <CAN>
- je teklin2 ; BUT ignore other control chars
- cmp al,escape ; escape?
- je teklin1 ; e = yes, come back to this state
- ret ; ignore stray control char
- teklin1:jmp tekctl ; process control char
- teklin2:mov lastc,0 ; clear last drawing coordinate flag
- mov visible,0 ; invisible again
- jmp tektxt ; process char under text mode
-
- teklin3:call tekxyc ; parse coordinates from input bytes
- jc teklin4 ; c = done, do the plotting
- ret ; nc = not done yet
- teklin4:mov cl,visible ; get moveto or drawto variable
- call tekdraw ; move that point
- mov visible,1 ; say next time we draw
- ret
- TEKLINE endp
-
- TEKPNT proc near ; FS plot single point
- cmp al,' ' ; control char?
- jae tekpnt3 ; ae = no
- cmp al,CR ; exit drawing on CR,LF,RS,US,FS,CAN
- je tekpnt2 ; e = yes, a cr
- cmp al,LF ; these terminate line drawing cmds
- je tekpnt2
- cmp al,FS ; <FS>
- je tekpnt2
- cmp al,GS ; <GS>
- je tekpnt2
- cmp al,RS ; <RS>
- je tekpnt2
- cmp al,US ; <US>
- je tekpnt2
- cmp al,CAN ; and <CAN>
- je tekpnt2 ; BUT ignore other control chars
- cmp al,escape ; escape?
- je tekpnt1 ; e = yes
- clc
- ret ; ignore stray control char
- tekpnt1:jmp tekctl ; process control char
- tekpnt2:mov lastc,0 ; clear last drawing coordinate flag
- mov visible,0 ; invisible again
- jmp tektxt ; process char under text mode
-
- tekpnt3:call tekxyc ; parse coordinates
- jc tekpnt4 ; c = done, do the plotting
- ret ; nc = not done yet
- tekpnt4:xor cl,cl ; do not draw
- call tekdraw ; move to the point
- mov ax,si ; copy starting point to end point
- mov bx,di ; ax,bx,si,di are in PC coordinates
- mov cl,1 ; make plot visible
- call line ; draw the dot
- mov visible,0 ; return to invisibility
- clc
- ret
- TEKPNT endp
-
- ; Decode graphics x,y components. Returns carry set to say have all
- ; components for a line, else carry clear. Understands 4014 lsb extensions.
- ; Permits embedded escape sequences.
- TEKXYC proc near
- cmp al,40h
- jb tekgh2 ; 20-3F are HIX or HIY
- cmp al,60h ; 40-5F are LOX (causes beam movement)
- jb tekgh4 ; 60-7F are LOY
- ; extract low-order 5 bits of Y coord
- mov ah,tek_loy ; copy previous LOY to MSB (4014)
- mov tek_lsb,ah
- and al,1Fh ; LOY is 5 bits
- mov tek_loy,al
- cmp lastc,loy ; 2nd LOY in a row?
- je tekgh1 ; e = yes, then LSB is valid
- mov tek_lsb,0 ; 1st one, clear LSB
- tekgh1: mov lastc,loy ; LOY seen, expect HIX (instead of HIY)
- tekgh0: clc ; c clear = not completed yet
- ret
- tekghx: mov ttstate,offset tektxt ; go to TEKTXT next time
- mov lastc,0 ; clear last drawing coordinate flag
- or status,txtmode ; set text mode in status byte
- clc ; carry clear means done
- ret
-
- ; Extract high-order 5 bits (X or Y, depending on lastc)
- tekgh2: and ax,1Fh ; just 5 bits
- mov cl,5
- shl ax,cl ; shift over 5 bits
- cmp lastc,loy ; was last coordinate a low-y?
- je tekgh3 ; e = yes, parse hix
- mov tek_hiy,ax ; this byte has HIY
- mov lastc,hiy
- clc
- ret
- tekgh3: mov tek_hix,ax ; this byte has HIX
- mov lastc,hix
- clc
- ret
- tekgh4: and al,1Fh ; just 5 bits
- mov tek_lox,al
- mov lastc,lox
- mov ax,tek_hix ; combine HIX*32
- or al,tek_lox ; with LOX
- mov bx,tek_hiy ; same for Y
- or bl,tek_loy
- stc ; set c to say completed operation
- ret
- TEKXYC endp
-
- TEKRLIN proc near ; RS relative line drawing
- cmp al,' ' ; control char?
- jae tekrli1 ; ae = no
- jmp tektxt ; process control char
- tekrli1:cmp al,' ' ; pen up command?
- jne tekrli2 ; ne = no, try pen down
- mov visible,0 ; do invisible movements
- jmp short tekrli3 ; do the command
- tekrli2:cmp al,'P' ; pen down command?
- jne tekrli4 ; ne = no, return to text mode
- mov visible,1 ; set visible moves
-
- tekrli3:mov ax,x_coord ; PC x coordinate of pen
- mov bx,y_coord ; y coordinate
- call pctotek ; get current pen position in Tek coor
- xor cl,cl ; invisible, moveto
- call tekdraw ; move that point, set oldx and oldy
- mov ttstate,offset tekinc ; next get incremental movement cmds
- ret
-
- tekrli4:mov visible,0 ; bad char, reset visibility
- mov ttstate,offset tektxt ; assume text
- tekrli5:jmp ttstate ; deal with bad char
- TEKRLIN endp
- ; interpret RS inc plot command byte
- TEKINC proc near ; get movement character and do cmd
- cmp al,' ' ; control char?
- jae tekinc1 ; ae = no
- jmp tektxt ; process control char
- tekinc1:mov bx,oldx
- mov cx,oldy
- test al,1 ; 'A', 'E', 'I'? Do by bit fields
- jz tekinc2 ; z = no
- inc bx ; adjust beam position
- tekinc2:test al,2 ; 'B', 'F', 'J'?
- jz tekinc4
- dec bx
- tekinc4:test al,4 ; 'D', 'E', 'F'?
- jz tekinc8 ; z = no
- inc cx
- tekinc8:test al,8 ; 'H', 'I', 'J'?
- jz tekinc9
- dec cx
- tekinc9:cmp bx,0 ; too far left?
- jge tekinc10 ; ge = no
- xor bx,bx ; else stop at the left margin
- tekinc10:cmp bx,maxtekx-1 ; too far left?
- jle tekinc11 ; le = no
- mov bx,maxtekx-1 ; else stop that the left margin
- tekinc11:cmp cx,maxteky-1 ; above the top?
- jle tekinc12 ; le = not above the top
- mov cx,maxteky-1 ; else stop at the top
- tekinc12:cmp cx,0 ; below bottom?
- jge tekinc13 ; ge = not below bottom
- xor cx,cx ; else stop at the bottom
- tekinc13:mov ax,bx ; ax is vector x end point
- mov oldx,bx
- mov bx,cx ; bx is vector y end point
- mov oldy,cx
- mov cl,visible
- jmp tekdraw ; move/draw to that point
- tekincb:mov visible,0
- jmp tektxt ; reparse the bad char
- TEKINC endp
-
-
- crossini proc near ; set crosshairs for initial screen
- cmp crossactive,0 ; inited already?
- je crossin1 ; e = no
- ret
- crossin1:mov ax,xmax ; right margin minus 7 dots
- add ax,7 ; right most dot
- shr ax,1 ; central position
- mov bx,ybot ; last scan line
- shr bx,1
- cmp ax,xcenter ; same as previous call?
- jne crossin2 ; ne = no, recenter
- cmp bx,ycenter ; same as previous call?
- je crossin3 ; e = yes, don't recenter crosshairs
- crossin2:
- mov xcenter,ax ; remember center coord
- mov ycenter,bx ; remember center coord
- mov xcross,ax ; save PC coord for crosshair
- mov ycross,bx
- crossin3: ; Mouse setup
- mov mousebuf,0 ; assume no active mouse driver
- mov al,mouse ; mouse interrupt 33h
- mov ah,35h ; get vector for mouse driver
- int dos
- mov ax,es
- cmp ax,0f000h ; in ROM Bios?
- jae crosin4 ; ae = yes
- or ax,bx ; check for no vector at all
- jz crosin4 ; z = none
- cmp byte ptr es:[bx],0cfh ; is this an IRET instruction?
- je crosin4 ; e = yes, not our driver
- mov ax,msgetbf ; get state buffer size (bytes) to BX
- int mouse
- add bx,15 ; round up to next paragraph
- shr bx,1
- shr bx,1
- shr bx,1
- shr bx,1 ; bytes to paragraphs
- mov ah,alloc ; allocate memory
- int dos
- jc crosin4 ; c = failed
- mov mousebuf,ax ; save seg of the mouse status buffer
- mov es,ax
- xor dx,dx ; buffer address to es:dx
- mov ax,msgetst ; get mouse state info
- int mouse
- jnc crosin2 ; nc = presumed success
- call mousefree ; return mouse save buffer
- jmp short crosin4
- crosin2:xor cx,cx ; minimum horizontal/vertical motion
- mov dx,xmax ; right most char
- add dx,7 ; right most dot (counted from 0)
- mov ax,mshoriz ; set min/max horizontal motion
- int mouse
- mov dx,ybot ; max y (counted from 0)
- mov ax,msvert ; set min/max vertical motion
- int mouse
-
- crosin4:mov ax,linepat ; save line drawing pattern
- mov ginlpsave,ax ; save it here
- mov linepat,0ffffh ; reset line type to solid
- cmp tekflg,tek_active+tek_sg; in DG special graphics mode?
- jne crosin5 ; e = yes, DG uses left bottom corner
- or dgcross,1 ; say crosshair is activiated
- and dgcross,not 8 ; and not invisible
- mov xcross,0 ; left side
- mov ax,ybot
- sub ax,charhgt ; skip status line
- mov ycross,ax ; bottom
- crosin5:call crosdrawh ; draw initial crosshairs
- call crosdrawv
- call setmouse ; set mouse there too
- mov crossactive,1 ; say we are active
- ret
- crossini endp
-
- crossfin proc near
- cmp crossactive,0 ; is crosshair material active?
- je crossfin1 ; e = no
- mov crossactive,0
- call crosdrawh ; erase crosshairs
- call crosdrawv
- call mousefree ; return mouse save buffer
- mov ax,ginlpsave
- mov linepat,ax ; restore line pattern
- mov ttstate,offset tektxt ; go to TEKTXT next time
- mov lastc,0 ; clear last drawing coordinate flag
- or status,txtmode ; set text mode in status byte
- crossfin1:ret
- crossfin endp
-
- ; Routine to trigger the crosshairs, wait for a key to be struck, and send
- ; the typed char (if printable ascii) plus four Tek encoded x,y position
- ; coordinates and then a carriage return.
- ; ax, cx, xcross, ycross operate in PC coordinates.
- ; For DG special graphics enter with scan code in AL
- CROSHAIR PROC FAR
- cmp tekflg,tek_active+tek_sg; in DG special graphics mode?
- jne crosha1a ; ne = no, try regular Tek GIN mode
- test dgcross,8 ; should be on but has been removed?
- jz crosha5 ; z = no, cross is visible
- push ax
- call crosdrawv ; show vertical line
- call crosdrawh
- pop ax
- and dgcross, not 8 ; say cross is visible again
- crosha5:test dgcross,2 ; track keyboard?
- jz crosha1 ; z = no, try mouse
- or al,al ; anything in keyboard trapping buf?
- jnz crosha4b ; process it as if key scan code
- crosha1:test dgcross,4 ; track mouse?
- jnz short crosha1c ; nz = yes, try the mouse
- jmp croshaexit ; neither, do nothing
- crosha1a:
- call tiseof ; is stdin at EOF?
- jc crosha2 ; c = yes, exit this mode now
- mov dl,0ffh
- mov ah,dconio ; read console
- int dos
- jnz crosha4 ; nz = have char in AL
- crosha1c:
- cmp mousebuf,0 ; is mouse driver active?
- je croshaexit ; e = no
- mov ax,msread ; mouse, read status and position
- int mouse
- push bx ; save button press information
- cmp cx,xcross ; moved in x direction?
- je crosm1 ; e = no
- push dx ; save mouse y
- call crosdrawv ; erase vertical line
- call crosdrawh
- mov xcross,cx ; new position
- call crosdrawv ; draw new vertical line
- call crosdrawh
- pop dx
- crosm1: cmp dx,ycross ; moved in y direction?
- je crosm2 ; e = no
- call crosdrawh ; erase horizontal line
- test dgcross,1 ; is DG crosshair active?
- jz crosm3 ; z = no
- call crosdrawv
- mov ax,ybot
- sub ax,charhgt ; avoid status line
- cmp dx,ax ; too far down?
- jbe crosm3 ; be = no
- mov dx,ax ; stop here
- crosm3: mov ycross,dx
- call crosdrawh ; draw new horizontal line
- test dgcross,1 ; is DG crosshair active?
- jz crosm3a ; z = no
- call crosdrawv
- crosm3a:call setmouse ; set mouse there too
- crosm2: pop bx
- test bx,7 ; mouse, was a button pressed?
- jz croshaexit ; z = no
- cmp tekflg,tek_active+tek_sg ; DG special graphics mode?
- je crosm4 ; e = yes, do POINT command
- mov al,CR ; simulate a CR
- jmp short crosha4
- crosm4: cmp bl,1 ; left button? (rt button is 2)
- je crosm5 ; e = yes
- mov al,RS ; send DG F1 code RS q for EXECUTE
- call outmodem
- mov al,'q'
- call outmodem
- clc
- ret
- crosm5: call dgcrossrpt ; send DG POINT command
- croshaexit:clc ; c clear means not done yet
- ret
-
- crosha4:or al,al ; ascii or scan code returned
- jnz arrow5 ; nz = ascii char returned
- call tiseof ; is stdin at EOF?
- jc crosha2 ; c = yes, exit this mode now
- mov ah,coninq ; read scan code
- int dos
- crosha4b:
- or al,al ; Control-Break?
- jnz crosha3 ; nz = no, something else
- crosha2:call crosdrawh ; erase crosshairs
- call crosdrawv
- mov ax,ginlpsave
- mov linepat,ax ; restore line pattern
- ret ; exit crosshairs mode
-
- crosha3:cmp al,homscn ; is it 'home'?
- jne arrow1 ; ne = no, try other keys
- call crosdrawh ; erase crosshairs
- call crosdrawv
- mov ax,xmax ; right margin
- add ax,7
- shr ax,1 ; central position
- mov xcross,ax ; save PC coord for crosshair
- mov ax,ybot ; last scan line
- shr ax,1
- mov ycross,ax ; this is the center of the screen
- call crosdrawh ; draw home'd crosshairs
- call crosdrawv
- call setmouse ; set mouse there too
- jmp croshaexit
-
- arrow1: cmp al,lftarr ; left arrow?
- jne arrow2 ; ne = no
- mov cx,-1 ; left shift
- jmp short xkeys
- arrow2: cmp al,rgtarr ; right arrow?
- jne arrow3 ; ne = no
- mov cx,1 ; right shift
- jmp short xkeys
- arrow3: cmp al,uparr ; up arrow?
- jne arrow4 ; ne = no
- mov cx,-1 ; up shift
- jmp short vertkey
- arrow4: cmp al,dnarr ; down arrow?
- jne badkey ; ne = no, ignore it
- mov cx,1 ; down shift
- jmp short vertkey
-
- badkey: call tekbeep ; tell user we don't understand
- jmp croshaexit ; keep going
-
- ; Shifted keys yield ascii keycodes
- arrow5: cmp al,'C' and 1fh ; Control-C?
- je crosha2 ; e = yes, exit crosshairs mode now
- cmp al,shlftarr ; shifted left arrow?
- jne arrow6 ; ne = no
- mov cx,-10 ; big left shift
- jmp short xkeys
- arrow6: cmp al,shrgtarr ; shifted right arrow?
- jne arrow7 ; ne = no
- mov cx,10 ; big right shift
- jmp short xkeys
- arrow7: cmp al,shuparr ; shifted up arrow?
- jne arrow8 ; ne = no
- mov cx,-10 ; big up shift
- jmp short vertkey
- arrow8: cmp al,shdnarr ; shifted down arrow?
- jne charkey ; ne = no, send this key as is
- mov cx,10 ; big down shift
- jmp short vertkey
-
- xkeys: call crosdrawv ; erase vertical line
- call crosdrawh
- add cx,xcross ; add increment
- jns noxc ; gone too far negative?
- xor cx,cx ; s = yes, make it 0
- noxc: mov ax,xmax
- add ax,7 ; right most dot
- cmp cx,ax ; too far right?
- jb xdraw9 ; b = no
- mov cx,ax ; yes, make it the right
- xdraw9: mov xcross,cx ; new x value for cross hairs
- call crosdrawv ; draw new vertical line
- call crosdrawh
-
- call setmouse ; set mouse there too
- jmp croshaexit
-
- vertkey:call crosdrawh ; erase horizontal line
- call crosdrawv
- add cx,ycross ; adjust cx
- jns noyc ; gone negative?
- xor cx,cx ; s = yes then make 0
- noyc: test dgcross,1 ; is DG crosshair active?
- jz noyc2 ; z = no
- push ax
- mov ax,ybot
- sub ax,charhgt ; avoid status line
- cmp cx,ax ; too far down?
- jbe noyc1 ; be = no
- mov cx,ax ; stop here
- noyc1: pop ax
-
- noyc2: cmp cx,ybot ; too high?
- jb yok ; b = no
- mov cx,ybot ; make it maximum
- yok: mov ycross,cx ; save new y crosshair
- call crosdrawh ; draw new vertical line
- call crosdrawv
- call setmouse ; set mouse there too
- jmp croshaexit
-
- charkey:call outmodem ; send the break character
- mov ax,xcross ; set beam to xcross,ycross
- mov bx,ycross ; must convert to Tek coordinates
- call pctotek ; scale from PC screen coord to Tek
- push ax ; save around drawing
- push bx
- xor cx,cx ; just a move
- call tekdraw ; moveto ax,bx in Tek coord
- pop bx ; recover Tek y
- pop ax ; recover Tek x
- call sendpos ; send position report to host
- call crossfin ; finish up
- STC ; set carry to say end of GIN mode
- ret
- CROSHAIR ENDP
-
- ; draw vertical crosshair line at x = xcross, xor with picture
- crosdrawv proc near
- push bp
- push x_coord
- push y_coord
- mov al,ccode ; save current pixel op
- push ax
- push cx
- mov si,xcross ; move to x= xcross
- mov ax,si ; ending x coord
- xor di,di ; starting y coord
- mov bx,ybot ; bottom y coord
- test dgcross,1 ; DG cursor?
- jz crosdrawv2 ; z = no
- sub bx,charhgt ; omit status line
- test flags.vtflg,ttd470 ; D470 short cursor
- jz crosdrawv2 ; z = no, use D463 large cursor
- mov cx,charhgt
- shr cx,1 ; half a cell
- mov di,ycross ; D470 start at top of char cell
- mov bx,di
- sub bx,cx
- jnc crosdrawv1 ; nc = in bounds
- xor bx,bx ; clip at top
- crosdrawv1:
- add di,cx ; down half a cell
- mov cx,ybot
- sub cx,charhgt ; omit status line
- dec cx
- cmp di,cx ; too far down?
- jbe crosdrawv2 ; be = no
- mov di,cx ; clip at bottom
- crosdrawv2:mov cl,pixxor ; xor pixels
- call line ; draw vertical
- pop cx
- pop ax ; recover current pixel op
- mov ccode,al ; restore it
- pop y_coord
- pop x_coord
- pop bp
- ret
- crosdrawv endp
-
- ; draw horizontal crosshair line at y = ycross, xor with picture
- crosdrawh proc near
- push bp
- push x_coord
- push y_coord
- mov al,ccode ; save current pixel op
- push ax
- push cx
- mov di,ycross ; set y = ycross
- mov bx,di ; ending y
- xor si,si ; starting x
- mov ax,xmax
- add ax,7
- test dgcross,1 ; DG cross?
- jz crosdrawh1 ; z = no
- test flags.vtflg,ttd470 ; D470 short cursor
- jz crosdrawh1 ; z = no, use D463 large cursor
- mov si,xcross ; start x
- mov ax,si
- sub si,7
- add ax,7 ; width
- crosdrawh1:
- mov cl,pixxor ; set XOR code
- call line ; draw to (xcross+12, ycross)
- pop cx
- pop ax ; recover current pixel op
- mov ccode,al ; restore it
- pop y_coord
- pop x_coord
- pop bp
- ret
- crosdrawh endp
-
- ; Set mouse cursor position to xcross,ycross. Ignored if no active mouse.
- setmouse proc near
- cmp mousebuf,0 ; is mouse driver is active?
- je setmou1 ; e = no
- mov cx,xcross
- mov dx,ycross
- mov ax,mswrite ; set mouse position
- int mouse
- setmou1:ret
- setmouse endp
-
- ; Return DOS memory allocated as mouse status buffer
- mousefree proc near
- push es
- mov ax,mousebuf ; seg of mouse save buffer
- mov es,ax ; allocated segment
- mov ah,freemem ; free it
- int dos
- mov mousebuf,0 ; clear mouse presence too
- pop es
- ret
- mousefree endp
-
- ; Return mouse state and free state save buffer
- mousexit proc near
- mov ax,mousebuf ; segment of state save buffer
- or ax,ax ; is mouse driver active?
- jz mousex1 ; z = no
- push es
- mov es,ax
- xor dx,dx ; address is in es:dx
- mov ax,mssetst ; set mouse driver state from buffer
- int mouse
- pop es
- call mousefree ; return memory to DOS
- mousex1:ret
- mousexit endp
-
- ; SENDPOS sends position of cross-hairs to the host.
- ; ax has Tek X and bx has Tek Y coord of center of crosshair
- SENDPOS PROC NEAR
- push bx ; preserve register
- call sendxy ; send x coord
- pop ax
- call sendxy ; send y coord
- mov al,cr ; follow up with cr
- call outmodem
- ret
- SENDPOS ENDP
-
- ; Write binary number in AX as decimal asciiz to buffer pointer DI.
- dec2di proc near ; output number in ax using base in cx
- ; corrupts ax, cx, and dx
- mov cx,10
- dec2di1:xor dx,dx ; clear high word of numerator
- div cx ; (ax / cx), remainder = dx, quotient = ax
- push dx ; save remainder for outputting later
- or ax,ax ; any quotient left?
- jz dec2di2 ; z = no
- call dec2di1 ; yes, recurse
- dec2di2:pop dx ; get remainder
- add dl,'0' ; make digit printable
- mov [di],dl ; store char in buffer
- inc di
- mov byte ptr[di],0 ; add terminator
- ret
- dec2di endp
-
- ; SENDXY sends value of ax as Tek encoded bytes
- ; ax is in Tek coordinates
- SENDXY PROC NEAR
- shl ax,1
- shl ax,1 ; move all but lower 5 bits to ah
- shl ax,1
- shr al,1
- shr al,1 ; move low five bits to low 5 bits
- shr al,1
- or ah,20h ; make it a printing char as per TEK
- xchg al,ah ; send high 5 bits first
- call outmodem
- xchg al,ah ; then low five bits
- or al,20h
- call outmodem
- xchg ah,al ; al is first sent byte
- ret
- SENDXY ENDP
-
-
- SENDID PROC NEAR ; pretend VT340
- mov bx,offset tekid ; VT320 identification string
- sndid1: mov al,[bx] ; get char from sequence
- or al,al ; end of sequence?
- jz sndid0 ; z = yes, return
- call outmodem ; send it out the port
- inc bx
- jmp sndid1
- sndid0: ret
- SENDID ENDP
-
- ; SENDSTAT - send status and cursor position to host
-
- SENDSTAT PROC NEAR
- mov al,STATUS ; get tek status
- or al,20h ; make it printable
- call OUTMODEM ; and send it
- mov ax,oldx ; now send x coordinate (oldx is Tek)
- call SENDXY
- mov ax,oldy ; and y coordinate (oldy is Tek coord)
- call SENDXY
- mov al,cr ; end with a cr
- call OUTMODEM
- ret
- SENDSTAT ENDP
-
-
- ; Convert X and Y from PC coordinates to Tek coordinates. AX = X, BX = Y
- ; for both input and output.
- pctotek proc near
- mul xdiv ; scale from PC screen coord to Tek
- div xmult
- xchg bx,ax ; save Tek x coord in bx
- neg ax ; y axis. Turn upside down for Tek
- add ax,ybot
- mul ydiv ; scale y from PC screen coord to Tek
- div ymult
- xchg ax,bx ; ax has X, bx has Y in Tek coords
- ret
- pctotek endp
-
- ; Routine to output character in AL to the screen.
-
- OUTSCRN PROC NEAR ; put one character to the screen
- cmp rxtable+256,0 ; translation turned off?
- je outscr2 ; e = yes, no translation
- push bx
- mov bx,offset rxtable ; address of translate table
- xlatb ; new char is in al
- and al,7fh ; retain only lower seven bits
- pop bx
-
- outscr2:mov ah,ccode ; assume transparent chars
- push ax ; save ccode
- mov ccode,pixfor ; write in foreground
- cmp chcontrol,0 ; transparent char writing?
- je outscr3 ; e = yes
- or ccode,pixbak ; write background dots too
- outscr3:call remcursor ; remove text cursor symbol
- cmp al,' ' ; printable?
- ja outscr6 ; a = yes
- je outscr5 ; e = space
- outscr4:call putctrl ; handle controls at putctrl
- jmp short outscr9
- outscr5:cmp spcontrol,0 ; destructive space?
- jne outscr6 ; ne = yes, do actual writing
- cmp chcontrol,0 ; write transparently?
- jne outscr6 ; ne = no, opaque, draw the char
- call testfull ; check on full screen
- call incx ; move to next char position
- jmp short outscr9
-
- outscr6:call testfull ; check for full screen
- sub al,' ' ; Tek chars are biased to start at ' '
- call putc ; routine to draw characters
- outscr9:call setcursor ; draw text cursor symbol
- pop ax ; recover ccode
- mov ccode,ah
- ret
- OUTSCRN ENDP
-
- ; Data General D463/D470 support routine, used by touchup
- ; Display whole line, es:si holds char+attribute words, cursor is at DX
- ttxtline proc far
- push word ptr fontlptr
- push word ptr fontlptr+2
- push word ptr fontrptr
- push word ptr fontrptr+2
- push dx ; cursor position
- push bx
- test dgcross,1 ; is cross hair on?
- jz ttxtlin0 ; z = no
- test dgcross,8 ; is cross hair invisible?
- jnz ttxtlin0 ; nz = yes
- push es
- push si
- push dx
- call crosdrawh ; remove present crosshairs
- call crosdrawv
- or dgcross,8 ; say cross is invisible
- pop dx
- pop si
- pop es
- ttxtlin0:
- mov bl,dh ; get line row
- xor bh,bh
- mov charwidth,8 ; use regular width font
- cmp dgwindcomp[bx],0 ; regular width chars?
- pop bx
- je ttxtlin1 ; e = yes
- cmp plotptr,offset pltega ; ega dot plot routine?
- jne ttxtlin1 ; no, use 8 wide
- mov charwidth,5 ; use compressed font
- mov word ptr fontlptr,offset fivedot
- mov word ptr fontlptr+2,seg fivedot
- mov word ptr fontrptr+2,seg fivedot
- mov word ptr fontrptr,offset gr437
- cmp vtcpage,437 ; using CP437?
- je ttxtlin1 ; e = yes, use GR437 slim font
- mov word ptr fontrptr,offset gr850 ; GR850 slim font
- ttxtlin1:mov ccode,pixfor+pixbak
- mov ax,charhgt
- inc dh ; count text lines from 1
- mul dh ; compute scan row
- dec ax ; count scan lines from zero
- mov y_coord,ax
- mov x_coord,0
- mov cx,80 ; normal columns/screen
- cmp charwidth,8 ; wide chars?
- je ttxtlin2 ; e = yes
- mov cx,128 ; 128*5=640
- ttxtlin2:push charwidth
- mov ax,es:[si] ; char+attribute from virtual screen
- add si,2
- cmp al,' ' ; space is same pattern, use short cut
- je ttxtlin2a ; e = space
- cmp charwidth,8 ; can we use byte-wise short cut?
- jne ttxtlin4 ; ne = no
- ttxtlin2a:push di
- push ax
- sub si,2
- mov di,si
- cld
- repe scasw ; find repeats
- je ttxtlin3
- sub di,2 ; inc'd beyond break word, backup
- add cx,2 ; and the counter
- ttxtlin3:mov ax,di
- sub ax,si ; qty repeated, cx dec'd too
- mov si,di ; update source pointer
- shr ax,1 ; count words
- cmp ax,1
- jbe ttxtlin3a ; be = no change to charwidth
- mul charwidth
- mov charwidth,ax ; make wider chars from repeats
- ttxtlin3a:pop ax
- pop di
-
- ttxtlin4:push es
- push si
- push cx
- mov gfcol,ah ; foreground color
- and gfcol,0fh ; lower four bits
- cmp plotptr,offset pltega ; ega dot plot routine?
- je ttxtlin4a ; e = yes
- xor ah,ah ; no background for monochrome systems
- and al,7fh ; no high bit
- sub al,' ' ; font begins with space
- jnc ttxtlin4a ; nc = not a control
- xor al,al
- ttxtlin4a:mov cl,4
- shr ah,cl
- and ah,0fh
- mov gbcol,ah ; background color
- call putc ; draw the char, cursor done separately later
- pop cx
- pop si
- pop es
- pop charwidth
- dec cx
- jle ttxtlin6
- jmp ttxtlin2
-
- ttxtlin6:pop dx ; recover cursor
- pop word ptr fontrptr+2
- pop word ptr fontrptr
- pop word ptr fontlptr+2
- pop word ptr fontlptr
- ret
- ttxtline endp
-
- ; display char in AL, normal attributes in AH, text screen at DX
- ttxtchr proc far
- push cx
- push dx
- push word ptr fontlptr
- push word ptr fontlptr+2
- push word ptr fontrptr
- push word ptr fontrptr+2
- mov bl,dh ; get line row
- xor bh,bh
- mov charwidth,8 ; use regular width font
- cmp dgwindcomp[bx],0 ; regular width chars?
- je ttxtchr1 ; e = yes
- cmp plotptr,offset pltega ; ega dot plot routine?
- jne ttxtchr1 ; no, use 8 wide
- mov charwidth,5 ; use compressed font
- mov word ptr fontlptr,offset fivedot
- mov word ptr fontlptr+2,seg fivedot
- mov word ptr fontrptr+2,seg fivedot
- mov word ptr fontrptr,offset gr437
- cmp vtcpage,437 ; using CP437?
- je ttxtchr1 ; e = yes, use GR437 slim font
- mov word ptr fontrptr,offset gr850 ; GR850 slim font
- ttxtchr1:mov ccode,pixfor+pixbak
- mov gfcol,ah ; foreground color
- and gfcol,0fh ; lower four bits
- cmp plotptr,offset pltega ; ega dot plot routine?
- je ttxtchr2 ; e = yes
- xor ah,ah ; no background on monochrome systems
- and al,7fh ; no high bit
- sub al,' ' ; font begins with space
- jnc ttxtchr2 ; nc = not a control
- xor al,al ; omit controls
- ttxtchr2:mov cl,4
- shr ah,cl
- and ah,0fh
- mov gbcol,ah ; background color
- push ax
- mov ax,charwidth
- mul dl ; compute scan column
- mov cx,xmax
- add cx,8 ; right most dot
- sub cx,charwidth ; right most char cell
- cmp cx,ax ; char still on screen?
- jc ttxtchr2a ; c = out of range
- mov x_coord,ax
- ttxtchr2a:pop ax
- jc ttxtchr5 ; c = out of range
- push ax
- mov ax,charhgt
- inc dh ; count text lines from 1
- mul dh ; compute scan row
- dec ax ; count scan lines from zero
- mov y_coord,ax
- pop ax
- mov cursorst,0 ; say cursor is off (is overwritten)
- test dgcross,1 ; is cross hair on?
- jz ttxtchr3 ; z = no
- test dgcross,8 ; is cross hair invisible?
- jnz ttxtchr3 ; nz = yes
- push es
- push si
- push dx
- push ax
- call crosdrawh ; remove present crosshairs
- call crosdrawv
- or dgcross,8 ; say cross is on but invisible
- pop ax
- pop dx
- pop si
- pop es
- ttxtchr3:call putc ; draw the char, cursor done separately later
- ttxtchr5:
- pop word ptr fontrptr+2
- pop word ptr fontrptr
- pop word ptr fontlptr+2
- pop word ptr fontlptr
- pop dx
- pop cx
- ret
- ttxtchr endp
-
- ; Test if screen is full. If full sound beep, wait for any keyboard input
- ; (skip kbd reading if stdin is redirected).
- testfull proc near
- push ax
- mov ax,x_coord
- cmp ax,xmax ; at end of the line?
- jbe testfu1 ; be = no
- mov x_coord,0 ; wrap to next line
- mov ax,charhgt
- add y_coord,ax ; next row
- testfu1:mov ax,ybot ; get last scan line
- inc ax ; number of scan lines
- cmp ax,y_coord ; minus where char bottom needs to go
- jae testfu3 ; ae = enough space for char
- call tekbeep ; tell the user we are waiting
- call tiseof ; EOF on redirected stdin?
- jc testfu2 ; c = yes, proceed anyway
- mov ah,coninq ; read keyboad via DOS
- int dos ; wait for keystroke
- or al,al ; scan code being returned?
- jne testfu2 ; ne = no
- mov ah,coninq ; clear away scan code too
- int dos
- testfu2:call tekcls ; clear the screen
- mov x_coord,0
- mov y_coord,0
- testfu3:pop ax ; recover current character
- ret
- testfull endp
-
- ; Draw text cursor symbol by xor-ing. Sets xcursor,ycursor to symbol position.
- teksetcursor proc FAR
- call remcursor ; remove old cursor
- test atctype,4 ; is cursor to be invisible?
- jz teksetcur1 ; z = no
- ret
- teksetcur1:
- push ax
- mov ax,charhgt
- inc dh ; count text rows from 1
- mul dh ; compute scan row
- dec dh ; restore DX
- dec ax ; count scan rows from 0
- mov y_coord,ax
- push bx
- mov bl,dh ; get line row
- xor bh,bh
- mov ax,8 ; use regular width font
- cmp dgwindcomp[bx],0 ; regular width chars?
- pop bx
- je teksetcur3 ; e = yes
- cmp plotptr,offset pltega ; ega dot plot routine?
- jne teksetcur3 ; no, use 8 wide
- mov ax,5 ; use compressed font
- teksetcur3:
- mov charwidth,ax
- mul dl ; compute scan column
- push cx
- mov cx,xmax
- add cx,8
- sub cx,charwidth
- cmp ax,cx
- jbe teksetcur4 ; be = in range
- mov ax,cx
- teksetcur4:pop cx
- mov x_coord,ax
- pop ax
- call setcursor
- ret
- teksetcursor endp
-
- setcursor proc near
- cmp tekcursor,0 ; suppress cursor?
- je setcurs0 ; e = yes
- cmp cursorst,0 ; is cursor off now?
- jne setcurs0 ; ne = no
- cmp putc,offset mputc ; pure mono character display routine?
- jne setcurs1 ; ne = no
- setcurs0:ret ; no cursor for pure mono
- setcurs1:push ax
- push bx
- push cx
- push dx
- push si
- push di
- push es
- mov bh,gbcol
- mov bl,gfcol
- push bx
- mov bh,ccode ; current drawing code, save it
- push bx ; save ccode
- push x_coord ; save current operating point (PC)
- push y_coord
- mov ax,x_coord ; where cursor symbol starts, X axis
- mov bx,xmax
- add bx,8 ; real screen width
- sub bx,charwidth ; where last char could go
- cmp ax,bx ; beyond last character position?
- jbe setcurs2 ; be = no
- mov ax,bx ; yes, stop at last, for wrapping
- setcurs2:mov xcursor,ax ; remember where we drew symbol
- mov x_coord,ax ; set this for drawing the symbol
- mov ax,y_coord
- mov ycursor,ax
- push word ptr fontlptr ; save active font GLeft pointer
- push word ptr fontlptr+2
- mov ax,charwidth
- mov curcharw,ax ; current cursor width
- mov ax,seg defcurpat ; default Tek cursor pattern, seg
- mov word ptr fontlptr+2,ax ; point to us
- mov ax,offset defcurpat ; default Tek cursor pattern
- xor bl,bl ; initial (and only char in font)
- test tekflg,tek_sg ; special graphics?
- jz setcurs4 ; z = no, use default
- call dgsetcol
- and al,0fh ; retain foreground dots
- mov gfcol,al ; set foreground coloring
- mov cl,atctype ; active cursor type
- mov dgctype,cl ; type of cursor being written
- xor ch,ch
- jcxz setcurs5 ; z = nothing to do
- and cl,3 ; visible cursor kinds, two bits
- mov ax,offset dgcurbpat ; block pattern
- cmp cl,1 ; underline?
- ja setcurs3 ; a = no, block
- mov ax,offset dgcurupat ; use DG cursor underline pattern
- setcurs3:cmp plotptr,offset pltega ; ega dot plot routine?
- je setcurs4 ; e = yes, else CGA style
- add ax,5 ; use lower lines of 14L pattern
- setcurs4:mov word ptr fontlptr,ax ; set offset of pattern
- mov al,gfcol ; get foreground coloring
- xor ah,ah
- mov gbcol,ah ; no change to background
- mov curgcol,ax ; save it for cursor removal
- mov ccode,pixxor ; xor with foreground coloring
- mov al,bl ; symbol code to draw, first in font
- call putc ; routine to draw characters
- setcurs5:
- pop word ptr fontlptr+2
- pop word ptr fontlptr
- pop y_coord
- pop x_coord
- pop bx ; recover ccode
- mov ccode,bh
- mov cursorst,1 ; say cursor is on
- pop bx
- mov gbcol,bh
- mov gfcol,bl
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- setcursor endp
-
- ; Remove text cursor symbol by xor-ing with itself. Xcursor, ycursor is the
- ; PC coord of the cursor symbol.
- tekremcursor proc FAR
- call remcursor
- ret
- tekremcursor endp
-
- remcursor proc near
- cmp tekcursor,0 ; suppress cursor?
- je remcurs0 ; e = yes
- cmp cursorst,0 ; is cursor off now?
- je remcurs0 ; e = yes
- cmp putc,offset mputc ; pure mono character display routine?
- jne remcurs1 ; ne = no
- remcurs0:ret ; no cursor for pure mono
- remcurs1:push ax
- push bx
- push cx
- push dx
- push si
- push di
- push es
- mov bh,gbcol
- mov bl,gfcol
- push bx
- mov bh,ccode ; current drawing code, save it
- push bx ; save ccode
- push x_coord ; save current operating point (PC)
- push y_coord
- mov ax,xcursor ; where last cursor was written
- mov x_coord,ax ; setup for xor writing to remove it
- mov ax,ycursor
- mov y_coord,ax
- push word ptr fontlptr
- push word ptr fontlptr+2
- push charwidth
- mov ah,gbcol
- mov al,gfcol
- push ax
- mov ax,curcharw ; get old cursor char width
- mov charwidth,ax
- mov ax,curgcol ; get old cursor colors
- mov gfcol,al ; set it for removal
- mov ax,seg defcurpat
- mov word ptr fontlptr+2,ax ; point to our data segment
- mov ax,offset defcurpat ; default cursor pattern
- xor bl,bl ; initial (and only char in font)
- test tekflg,tek_sg ; special graphics?
- jz remcurs4 ; z = no, use default
- mov cl,dgctype ; last used emulation cursor type
- and cl,3 ; keep just two lower bits
- xchg dgctype,cl ; update cursor type
- xor ch,ch
- jcxz remcurs5 ; z = nothing to do
- mov ax,offset dgcurbpat ; use block pattern
- cmp cl,2 ; last used cursor type
- je remcurs3 ; 0/4 is no cursor, 1=uline, 2=block
- mov ax,offset dgcurupat ; use DG cursor underline pattern
- remcurs3:cmp plotptr,offset pltega ; ega dot plot routine?
- je remcurs4 ; e = yes, else CGA 8x8 style
- add ax,5 ; use lower scan lines for mono
- remcurs4:mov word ptr fontlptr,ax
- mov ccode,pixxor ; xor with foreground coloring
- mov gbcol,0 ; no change to background
- mov al,bl ; character from font
- call putc ; routine to draw characters
- remcurs5:
- pop ax
- mov gbcol,ah
- mov gfcol,al
- pop charwidth
- pop word ptr fontlptr+2
- pop word ptr fontlptr
- pop y_coord
- pop x_coord
- pop bx ; recover ccode
- mov ccode,bh
- mov cursorst,0 ; say cursor is off
- pop bx
- mov gbcol,bh
- mov gfcol,bl
- pop es
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- remcursor endp
-
- ; TEKCLS routine to clear the screen.
- ; Entry point tekcls1 clears screen without resetting current point.
- TEKCLS PROC NEAR
- test tekflg,tek_active ; Tek mode active yet?
- jnz tekcls0 ; nz = yes
- ret ; else ignore this call
- tekcls0:mov x_coord,0 ; starting text coordinates
- mov y_coord,0
- mov oldx,0 ; assumed cursor starting location
- mov oldy,maxteky ; top right corner (Tek coord)
- mov scalex,0 ; clear last plotted point (PC coord)
- mov scaley,0
- mov lastc,0 ; last parsed x,y coordinate
- mov visible,0 ; make lines invisible
- mov bypass,0 ; clear bypass condition
- mov ttstate,offset tektxt ; do displayable text
- mov prestate,offset tektxt
- tekcls1:push ax ; save registers
- push cx
- mov bl,ccode ; save pixel op code
- push bx
- cmp graph_mode,hercules ; Hercules?
- jne tekclsw ; ne = no
- call hgraf ; set Hercules board to Graphics mode
- jmp tekcls7
-
- tekclsw:cmp graph_mode,wyse700 ; Wyse 700?
- jne tekcls2 ; ne = no
- call wygraf ; set board to Graphics mode & cls
- jmp tekcls7
-
- tekcls2:xor di,di ; point to start of screen, di=row
- mov ccode,pixbak ; write in background
- call psetup ; setup graphics routine and es:di
- mov cx,4000h ; CGA, 200 lines times 80 bytes worth
- cmp graph_mode,cga ; cga?
- je tekcls3 ; e = yes
- mov cx,8000h ; Olivetti, 400 lines times 80 bytes
- cmp graph_mode,olivetti ; AT&T-Olivetti?
- je tekcls3 ; e = yes
- cmp graph_mode,toshiba ; Toshiba?
- je tekcls3 ; e = yes
- cmp graph_mode,vaxmate ; VAXmate?
- jne tekcls4 ; ne = no
- tekcls3:cld ; clear screen directly of text stuff
- xor ax,ax
- test gbcol,7 ; background is dark?
- jz tekcls3a ; z = yes
- mov ax,0ffffh ; light, set all pixels
- tekcls3a:shr cx,1 ; do words
- rep stosw ; clear the words
- jmp short tekcls7
-
- tekcls4:cmp graph_mode,ega ; EGA?
- je tekcls5 ; e = yes
- cmp graph_mode,monoega ; EGA with mono display?
- je tekcls5 ; e = yes
- cmp graph_mode,colorega ; EGA with medium resolution monitor?
- je tekcls5 ; e = yes
- jmp short tekcls6 ; else use Bios
-
- tekcls5: ; EGA clear screen quickly
- mov ax,0ff08h ; set all 8 bits to be changed
- call ega_gc ; set bit mask register accordingly
- mov ax,0003h ; data rotate reg, write unmodified
- call ega_gc ;
- mov cx,ybot ; last scan line
- inc cx ; number of scan lines
- mov ax,80/2 ; words (2*bytes) per scan line
- mul cx
- mov cx,ax ; cx = number of bytes to clear
- cmp tekflg,tek_active+tek_sg; in special graphics mode?
- jne tekcls5a ; ne = no, try regular Tek GIN mode
- test flags.vtflg,ttd463+ttd470 ; doing DG D463/D470 emulation?
- jz tekcls5a ; z = no
- call dgsetcol
- jmp short tekcls5b
- tekcls5a:call fixcolor ; fix colors first, if req'd
- tekcls5b:mov al,gbcol ; select background colour
- mov ah,al ; copy for word stores
- cld
- rep stosw ; write backgound color
- jmp short tekcls7
-
- tekcls6:push es ; clear screen by scrolling up
- call tcmblnk ; clear screen, for Environments
- pop es
-
- tekcls7:xor si,si ; starting x (in case screen is
- xor di,di ; starting y cleared by user)
- pop bx
- mov ccode,bl ; restore pixel op code
- mov xcursor,0 ; position of text cursor symbol
- mov ycursor,0
- mov cursorst,0 ; cursor has been erased
- call setcursor ; draw text cursor symbol
- pop cx
- pop ax
- ret
- TEKCLS ENDP
-
- ; Routine to draw a line on the screen, using TEKTRONIX coordinates.
- ; X coordinate in AX, 0=left edge of screen, 1023=right edge of screen.
- ; Y coordinate in BX, 0=bottom of screen, 779=top of screen.
- ; CL=0 - invisible move, else draw in foreground colors
-
- TEKDRAW PROC NEAR
- mov si,scalex ; get old x already scaled
- mov di,scaley ; get old y already scaled
- call scale ; scale new end point to PC coords
- or cl,cl ; invisible drawing?
- jz moveto ; z = just move, skip draw part
- mov cl,pixfor ; draw in foreground color
- call LINE ; draw the line
- moveto: mov x_coord,ax ; update text coordinates to match
- mov y_coord,bx ; last drawn point
- ret
- TEKDRAW ENDP
-
- ; Scale TEKTRONIX coordinates to the currently defined screen coordinates
- ; AX holds X axis, BX holds Y axis. Both are changed from Tektronix coord
- ; to PC coordinates by this procedure.
- SCALE PROC NEAR
- push dx
- push si
- cmp ax,1023 ; limit x axis
- jbe scale1 ; be = not out of bounds
- mov ax,1023
- scale1: cmp bx,779 ; limit y axix
- jbe scale2 ; be = not out of bounds
- mov bx,779
- scale2: mov oldx,ax ; save current Tek x for next draw
- mov oldy,bx ; save current Tek y for next draw
- mul xmult ; scale x-coord
- mov si,xdiv ; get the divisor
- shr si,1 ; halve it
- add ax,si ; add in - to round to nearest integer
- adc dx,0
- div xdiv
- push ax
- mov ax,bx
- mul ymult ; scale y-coord
- mov si,ydiv ; get divisor
- shr si,1 ; halve it
- add ax,si ; add in - to round to nearest integer
- adc dx,0
- div ydiv
- mov bx,ybot
- sub bx,ax ; put new Y in right reg
- jns scale3 ; ns = not too far
- xor bx,bx
- scale3: pop ax ; put new X in right reg
- mov scalex,ax ; save scaled values
- mov scaley,bx
- pop si
- pop dx
- ret
- SCALE ENDP
-
- ; LINE Subroutine to plot a line with endpoints in AX,BX and SI,DI.
- ; fast line drawing routine for the IBM PC
- ;
- ; Registers at CALL
- ; -----------------
- ; SI=Start X coord, all in PC coordinates
- ; DI=Start Y coord
- ; AX=End X coord
- ; BX=End Y coord
- ; CCODE=CL=pixel operation code
- ; LINEPAT=BP= line drawing pattern (is changed here by rotation)
- ; registers are all unchanged
-
- LINE PROC NEAR
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- push es
- mov bp,linepat ; store active line pattern word in BP
- mov dl,ccode ; existing pixel op code
- push dx ; save around line drawing
- mov ccode,cl ; save color code in ccode for use by plot()
- ; first get coord to achieve increasing x; deltax >= 0
- sub ax,si ; deltax = x2 - x1
- jge line1 ; ge = going to the right, as desired
- neg ax ; make deltax non-negative
- sub si,ax ; swap the x coordinates
- xchg bx,di ; swap the y coordinates too
- ; second, compute deltay. ax = deltax, si = x1
- line1: sub bx,di ; deltay = y2 - y1
- call psetup ; setup display adapter for plotting
- ; and setup es:di to screen memory
- ; Choose algorithm based on |deltay| < |deltax| (use shallow) else steep.
- ; We arrange matters such that both deltas are non-negative.
- or bx,bx ; deltay
- jge line2 ; ge = non-negative
- neg linelen
- neg bx ; make non-negative
- line2: cmp bx,ax ; |deltay| versus |deltax|
- jbe shallow ; be = do shallow algorithm
- jmp steep ; else do steep algorithm
-
- ; shallow algorithm, move along x, di=y1, bx=deltay, si=x1, ax=deltax
- shallow:add bx,bx ; bx = 2*deltay
- mov cx,ax ; cx = number of steps (deltax here)
- inc cx ; loop dec's cx before testing
- mov dx,bx ; dx holds error
- sub dx,ax ; error = 2*deltay - deltax
- add ax,ax ; ax = 2*|deltax|
- shal1: call plotptr ; Plot(x,y)
- or dx,dx
- jle shal2 ; le = error <= 0
- call pincy ; increment y by one scan line
- sub dx,ax ; error = error - 2*deltax
- shal2: add dx,bx ; error = error + 2*deltay
- inc si ; x = next dot right
- loop shal1
- jmp short plotex
-
- ; steep algorithm, move along y, di=y1, bx=deltay, si=x1, ax=deltax
- steep: add ax,ax ; ax = 2*deltax
- mov dx,ax ; dx holds error
- sub dx,bx ; error = 2*deltax (ax) - deltay (bx)
- mov cx,bx ; cx = number of steps (deltay here)
- inc cx ; loop dec's cx before testing
- add bx,bx ; bx = 2*|deltay|
- stee1: call plotptr ; Plot(x,y) x = ax, y = di
- or dx,dx
- jle stee2 ; le error <= 0
- inc si ; x = next dot right
- sub dx,bx ; error = error - 2*deltay
- stee2: add dx,ax ; error = error + 2*deltax
- call pincy ; increment y
- loop stee1
- ;;; jmp plotex
-
- plotex: pop dx ; dl has orginal pixel op
- mov ccode,dl ; restore it
- pop es
- pop di
- pop si
- pop dx ; restore the world
- pop cx
- pop bx
- pop ax
- ret
- LINE ENDP
-
- ; Draw a rectangle.
- ; lower left corner: x = param[0], y = param[2], Tek coordinates
- ; distance: dx = param[4], dy = param[6], Tek coordinates, all positive
- rectdraw proc near
- push x_coord
- push y_coord
- mov ax,param[0] ; lower left corner is start, x part
- mov bx,param[2] ; y part
- push ax ; x0
- push bx ; y0
- xor cl,cl ; moveto
- call tekdraw
- pop bx
- pop ax
- add bx,param[6] ; y0 + dy
- mov cl,1 ; draw x0,y0 to x0,y0+dy
- push ax
- push bx
- call tekdraw
- pop bx
- pop ax
- add ax,param[4] ; x0+dx
- mov cl,1 ; draw x0,y0+dy to x0+dx,y0+dy
- push ax
- call tekdraw
- pop ax
- mov bx,param[2] ; y0
- push bx
- mov cl,1
- call tekdraw
- pop bx
- mov ax,param[0] ; x0
- mov cl,1
- call tekdraw ; complete the box
- pop y_coord
- pop x_coord
- ret
- rectdraw endp
-
- ; Fill a rectangle with a given pattern.
- ; lower left corner: x = param[0], y = param[2], Tek coordinates
- ; distance: dx = param[4], dy = param[6], Tek coordinates, all positive
- ; fill pattern = param[8]
- rectfil proc near
- push oldx
- push oldy ; save regular point/line old coords
- mov ax,param ; get Tek X coord of lower left corner
- mov bx,param[2] ; get Tek Y coord
- call scale ; convert to PC in ax,bx, scalex/y
- mov rectx1,ax ; lower left corner in PC coords
- mov recty1,bx
- mov ax,param ; convert ending points, start Tek X
- add ax,param[4] ; Tek X + DX
- mov bx,param[2] ; start Tek Y
- add bx,param[6] ; Tek Y + DY
- call scale
- pop oldy
- pop oldx
- mov rectx2,ax ; upper right corner PC X coord
- mov recty2,bx ; upper right corner PC Y coord
- mov si,rectx1 ; starting x PC coord to si
- mov di,recty2 ; starting y PC coord to di
- mov cx,recty1 ; plotting from top down on screen
- sub cx,bx ; cx = # scan lines - 1
- mov numlines,cx ; remember here
- mov bx,param[8] ; fill pattern number
- or bx,bx ; zero?
- jz rectfi1 ; z = yes, use current pointer
- cmp bx,numfil ; pattern number is too large?
- ja rectfi1 ; a = yes, use current pointer
- dec bx ; count internally from 0
- shl bx,1 ; make this a word pointer
- mov bx,fillist[bx] ; get pointer to pattern
- mov fillptr,bx ; remember it here
- rectfi1:mov cx,rectx2 ; ending x coord
- sub cx,rectx1 ; number of horizontal pixels - 1
- inc cx ; number of horizontal pixels
- call psetup ; set up dsp and di to screen offset
- ; di points to whole byte, do bits in byte in gfplot
- rectfi2:push bx
- mov bx,recty1 ; lower screen y (larger value)
- sub bx,numlines ; alignment: global screen sync
- and bx,7 ; modulo 8
- add bx,fillptr ; offset of fill pattern start
- mov bl,[bx] ; pattern byte
- mov fill,bl ; save here for gfplot
- pop bx
- call gfplot ; line fill routine
- call pincy ; next line
- dec numlines
- jns rectfi2 ; ns = more to do
- ret
- rectfil endp
-
- ; Data General D463/D470 plotting routines
-
- ; RS G B turn on DG crosshairs
- dgcrosson proc far
- test dgcross,1 ; on now?
- jnz dgcroson1 ; nz = yes
- call crossini ; init crosshair routine
- or dgcross,1 ; say crosshairs are on
- dgcroson1:ret
- dgcrosson endp
-
- ; RS G C turn off DG crosshairs
- dgcrossoff proc far
- test dgcross,1 ; off now?
- jz dgcrosof2 ; z = yes
- test dgcross,8 ; on but invisible?
- jz dgcrosof1 ; z = no
- call crosdrawh ; restore crosshairs
- call crosdrawv
- dgcrosof1:call crossfin ; finish crosshair routine & exit
- and dgcross,not 1+8 ; say crosshair is deactiviated
- dgcrosof2:ret
- dgcrossoff endp
-
- ; Set DG crosshairs to DG locations x (ax) and y (bx)
- dgsetcrloc proc far
- test dgcross,1 ; is cross hair on?
- jz dgsetcr1 ; z = no
- test dgcross,8 ; is cross hair invisible?
- jnz dgsetcr1 ; nz = yes
- push ax ; save arguments
- push bx
- call crosdrawh ; remove present crosshairs
- call crosdrawv
- pop bx
- pop ax
- dgsetcr1:cmp ax,dgxmax ; DG x max, exceeded?
- jb dgsetcr2 ; b = in range
- mov ax,dgxmax ; else set to max
- dec ax
- dgsetcr2:mov si,ax
- call dg2pcx ; convert DG to PC x in SI
- mov xcross,si
- mov di,bx
- call dg2pcy ; convert DG to PC y in DI
- sub di,ybot
- add di,charhgt
- neg di ; reflect top to bottom
- mov ycross,di
- test dgcross,1 ; is crosshair on?
- jz dgsetcr4 ; z = no
- call setmouse ; set the mouse there too
- call crosdrawh ; draw crosshairs
- call crosdrawv
- and dgcross,not 8 ; say cross is visible
- dgsetcr4:ret
- dgsetcrloc endp
-
- ; Data General D463/D470 RS G ? | report crosshair location
- dgcrossrpt proc far
- mov al,RS ; report RS O | <nnnnn> <nnnnn><CR>
- call outmodem
- mov al,'o' ; must be lower case, manual is wrong
- call outmodem
- mov al,'|'
- call outmodem
- mov al,' ' ; space separator
- call outmodem
- mov ax,xcross ; x PC coordinate
- mov cx,dgxmax ; DG max X
- mul cx
- mov cx,xmax ; max PC x coordinate
- add cx,7 ; account for char width effect
- div cx ; use quotient in AX
- call out5digit ; output 5 digit ASCII result
- mov al,' ' ; space separator
- call outmodem
- mov ax,ybot
- sub ax,charhgt
- mov cx,ax ; save PC screen height
- sub ax,ycross ; PC coordinates from bottom
- mul dgymax ; DG max y
- div cx ; use quotient in AX
- call out5digit ; output 5 digit ASCII result
- mov al,CR ; terminal character
- call outmodem
- ret
- dgcrossrpt endp
-
- ; send 5 digit ASCII number (zero filled on the left) found in AX
- out5digit proc near
- push di
- mov di,offset stripbc ; use this as temp buffer
- mov word ptr [di],'00'
- mov word ptr [di+2],'00'
- inc di ; first digit is always 0
- cmp ax,1000
- jae out5d2
- inc di
- cmp ax,100
- jae out5d2
- inc di
- cmp ax,10
- jae out5d2
- inc di
- out5d2: call dec2di ; convert and write to di
- mov di,offset stripbc
- mov cx,5
- out5d4: mov al,[di]
- push cx
- push di
- call outmodem
- pop di
- pop cx
- inc di
- loop out5d4
- pop di
- ret
- out5digit endp
-
- ; Set Data General coloring for graphics fore/background, gfcol and gbcol,
- ; by breaking apart the "curattr" from text mode.
- dgsetcol proc near
- push ax
- push cx
- mov al,curattr
- mov ah,al ; copy it
- and al,0fh ; isolate foreground color
- mov gfcol,al ; set it
- mov cl,4
- and ah,70h
- shr ah,cl ; get to background field
- cmp plotptr,offset pltega ; ega dot plot routine?
- je dgsetco2 ; e = yes
- cmp ah,al ; same color for fore/back?
- jne dgsetco1 ; ne = no
- mov gfcol,0 ; set foreground to black
- jmp short dgsetco2
- dgsetco1:xor ah,ah ; set background to black
- dgsetco2:mov gbcol,ah ; set it
- pop cx
- pop ax
- ret
- dgsetcol endp
-
- dgline proc far ; (x,y,x,y,pattern,mar_bot+mar_top)
- push bp
- mov bp,sp ; C calling convention
- push es
- push si
- push di
- push dx
- push linepat
- mov al,gfcol ; current screen background
- mov ah,gbcol
- push ax
- test dgcross,1 ; is cross hair on?
- jz dgline1 ; z = no
- test dgcross,8 ; is cross hair invisible?
- jnz dgline1 ; nz = yes
- call crosdrawh ; remove present crosshairs
- call crosdrawv
- or dgcross,8 ; say cross is invisible
- dgline1:call dgsetcol ; get current coloring
-
- mov di,[bp+6+6] ; end y, DG coordinates
- call dg2pcy ; scale to PC y in di
- add di,charhgt
- sub di,ybot
- neg di ; PC end y, top to bottom flip
- mov bx,di ; PC end y in BX
-
- mov di,[bp+6+2] ; start y, DG coordinates
- call dg2pcy ; scale to PC y in di
- add di,charhgt
- sub di,ybot
- neg di ; start y, top to bottom flip
-
- mov si,[bp+6+4] ; end DG X
- call dg2pcx ; convert to PC x in SI
- mov ax,si ; AX is end x
-
- mov si,[bp+6+0] ; start x
- call dg2pcx ; convert to PC x in SI
-
- mov cl,pixfor+pixbak ; do all dots
- push [bp+6+8] ; line pattern
- pop linepat ; set it
- call line ; draw the line
- pop ax
- mov gfcol,al
- mov gbcol,ah
- pop linepat
- pop dx
- pop di
- pop si
- pop es
- pop bp
- ret
- dgline endp
-
- dgbar proc far ; (startx,starty,width,height,code, mar_top, mar_bot)
- push bp
- mov bp,sp ; C calling convention
- push es
- push si
- push di
- push dx
- mov ah,gbcol
- mov al,gfcol
- push ax
-
- mov ax,charhgt ; current char height
- mov dx,[bp+6+10] ; dx = mar_top
- mul dl ; dots to top of mar_top line
- mov yresval,ax ; top margin line
- mov ax,charhgt ; current char height
- mov dx,[bp+6+12] ; dx = mar_bot
- mul dl ; dots to bot of mar_bot line
- add ax,charhgt ; dots to bottom of mar_bot line
- mov yresval+2,ax ; bottom margin line
-
- mov si,[bp+6+0] ; DG start x
- add si,[bp+6+4] ; DG x width
- call dg2pcx ; convert to PC x in SI
- mov ax,xmax
- add ax,7 ; right most dot
- cmp si,ax ; out of bounds?
- jbe dgbar1 ; be = no
- mov si,ax ; clip to right margin
- dgbar1: mov rectx2,si ; PC end/right x in rectx2
-
- mov si,[bp+6+0] ; DG start x
- call dg2pcx ; convert to PC x in SI
- mov rectx1,si ; PC start/left x in rectx1
-
- mov di,[bp+6+2] ; start y, DG coordinates
- add di,[bp+6+6] ; plus DG height
- call dg2pcy ; convert to PC y in DI
- add di,charhgt
- sub di,ybot
- neg di ; top to bottom flip
- cmp di,yresval ; above top margin line?
- jae dgbar2 ; ae = no
- mov di,yresval
- dgbar2: mov recty2,di ; PC end/top y in recty2
-
- mov di,[bp+6+2] ; start y, DG coordinates
- call dg2pcy ; convert to PC y in DI
- add di,charhgt
- sub di,ybot
- neg di ; top to bottom flip
- cmp di,yresval+2 ; below bottom margin?
- jbe dgbar3 ; be = no
- mov di,yresval+2 ; clip to bottom margin
- dgbar3: mov recty1,di ; PC start/bot y in recty1
- call remcursor ; remove text cursor
- test dgcross,1 ; is cross hair on?
- jz dgbar4 ; z = no
- test dgcross,8 ; is cross hair visible?
- jnz dgbar4 ; nz = no
- call crosdrawh ; remove present crosshairs
- call crosdrawv
- or dgcross,8 ; say cross is invisible
- dgbar4: mov si,rectx1 ; left x PC coord to si
- mov di,recty2 ; top y PC coord to di
- mov cx,recty1 ; plotting from top down on screen
- sub cx,di ; cx = # scan lines - 1
- inc cx
- mov numlines,cx ; remember here
- call dgsetcol
- mov ccode,pixfor ; write in foreground color
- cmp byte ptr [bp+6+8],0 ; color, 0=background, 1=foreground
- jne dgbar5 ; ne = foreground
- mov ccode,pixbak ; write in background color
- dgbar5: mov cx,rectx2 ; ending x coord
- sub cx,rectx1 ; number of horizontal pixels - 1
- inc cx ; number of horizontal pixels
- call psetup ; set up dsp and di to screen offset
- ; di points to whole byte, do bits in byte in gfplot
- mov fill,0ffffh
- dgbar6: call gfplot ; line fill routine, uses CX
- call pincy ; next line
- dec numlines
- cmp numlines,0 ; done all lines?
- jg dgbar6 ; g = still lines to do
- pop ax
- mov gbcol,ah
- mov gfcol,al
- pop dx
- pop di
- pop si
- pop es
- pop bp
- ret
- dgbar endp
-
- dgarc proc far ;dgarc(center x, center y, radius, start angle, end angle,
- ; mar_top, mar_bot)
- push bp
- mov bp,sp
- mov al,gfcol
- mov ah,gbcol
- push ax
- push si
- push di
- push es
- call remcursor ; remove text cursor
- call dgsetcol
- mov si,[bp+6+0] ; x center
- call dg2pcx ; x center in PC units in SI
- inc si ; plus one dot safety on PC screen
- mov scalex,si ; store here
-
- mov di,[bp+6+2] ; y center
- call dg2pcy ; y center in PC units in DI
- mov scaley,di ; store here
-
- mov ax,[bp+6+6] ; start angle for CCW motion
- xor dx,dx
- mov cx,360
- div cx ; start angle in ax, modulo 360
- mov angle,dx ; actual start angle, mod 360
-
- mov ax,[bp+6+8] ; end angle for CCW motion
- mov bx,[bp+6+6] ; start angle
- mov cx,bx
- add cx,ax
- cmp cx,720 ; more than one circle?
- jb dgarc1 ; b = no
- mov ax,cx ; make end angle much larger than strt
- cmp ax,bx ; less than starting angle?
- jae dgarc1 ; ae = no
- add ax,360 ; add one rev
- dgarc1: cmp ax,angle ; starting angle
- jae dgarc2 ; ae = angle <= angle+2, is ok
- cmp angle,360 ; special case?
- je dgarc2 ; e = yes
- xchg ax,angle ; make angle <= angle+2
- dgarc2: mov angle+2,ax ; ending angle
-
- mov ax,charhgt ; current char height
- mov dx,[bp+6+10] ; dx = mar_top
- mul dl ; dots to top of mar_top line
- mov yresval,ax ; top margin line
- mov ax,charhgt ; current char height
- mov dx,[bp+6+12] ; dx = mar_bot
- mul dl ; dots to bot of mar_bot line
- add ax,charhgt ; dots to bottom of mar_bot line
- mov yresval+2,ax ; bottom margin line
- test dgcross,1 ; is cross hair on?
- jz dgarc3 ; z = no
- test dgcross,8 ; is cross hair invisible?
- jnz dgarc3 ; nz = yes
- call crosdrawh ; remove present crosshairs
- call crosdrawv
- or dgcross,8 ; say cross is invisible
- dgarc3:
- mov dl,ccode ; existing pixel op code
- push dx ; save around line drawing
- push linepat
- mov si,[bp+6+4] ; radius
- mov di,si
- call dg2pcx ; x axis
- mov yresval+4,si ; save radius in PC x units
- call dg2pcy
- mov yresval+6,di ; save radius in PC y units
- call dg2pcx
-
- mov bx,angle ; start angle
- call dgasin ; convert point to SI,DI DG coord
- call dg2pcy ; and to PC y coordinate
- add di,scaley ; add center
- sub di,ybot
- add di,charhgt
- neg di
- mov recty1,di ; y1 in virtual units
-
- add si,scalex ; add center to PC x coord
- mov rectx1,si ; x1 in virtual units
- mov linepat,0ffffh
- mov bx,angle ; start angle
-
- dgarc4: inc bx ; step angle
- cmp bx,angle+2 ; done yet?
- jbe dgarc5 ; be = no
- mov bx,angle+2 ; end angle
- dgarc5: mov angle,bx ; new start
- call dgasin ; convert BX point to SI,DI PC coord
- add di,scaley ; add center
- sub di,ybot ; flip top to bottom
- add di,charhgt
- neg di
- mov recty2,di ; y2 in PC units
- add si,scalex ; add center
- mov rectx2,si ; x2 in PC units
-
- mov si,rectx1
- mov di,recty1 ; start x,y
- mov ax,rectx2
- mov bx,recty2 ; end x,y
- cmp di,yresval ; is start above top margin?
- jb dgarc6 ; b = yes, no plot
- cmp bx,yresval ; and end point?
- jb dgarc6 ; b = yes, no plot
- cmp di,yresval+2 ; is start below bottom margin?
- ja dgarc6 ; a = yes, no plot
- cmp bx,yresval+2 ; end point?
- ja dgarc6 ; a = yes, no plot
- mov cl,pixfor
- call line ; draw line segment
- dgarc6: mov ax,rectx2 ; shift end to start
- mov rectx1,ax
- mov ax,recty2
- mov recty1,ax
- mov bx,angle ; start angle
- cmp bx,angle+2 ; done to end angle yet?
- jb dgarc4 ; b = no
- pop linepat
- pop dx ; save around line drawing
- mov ccode,dl ; existing pixel op code
- pop es
- pop di
- pop si
- pop ax
- mov gfcol,al
- mov gbcol,ah
- pop bp
- ret
- dgarc endp
-
- ; Provide x,y coordinates in DG address frame, given radius and angle (deg,
- ; ccw from the positve x axis). X is in SI, Y is in DI.
- ; Radius is in yresval+4 for x and yresval+6 for y, angle is in bx.
- dgasin proc near ; x = r cos(theta), y = r sin(x)
- push ax
- push bx
- push cx
- push dx
- push es
- mov cx,seg sin ; sine lookup table, 90/64 deg steps
- mov es,cx
- mov ax,bx
- mov cx,360
- push dx
- xor dx,dx
- div cx ; remove extra 360's
- mov bx,dx ; keep remainder
- pop dx ; bx now has angle mod 360
- ; do quadrants
- xor si,si ; assume right side
- xor di,di ; and top
- cmp bx,180 ; left or right?
- jbe dgasin1 ; be = right
- mov di,-1 ; remember to flip sign
- sub bx,360
- neg bx
- dgasin1:cmp bx,90 ; top or bottom
- jbe dgasin2 ; be = top
- mov si,-1 ; say bottom
- sub bx,180 ; flip
- neg bx
- dgasin2:cmp bx,90 ; at the upper limit?
- jne dgsin2a ; ne = no
- mov ax,256 ; set 16 bit value
- jmp short dgsin2b
- dgsin2a:mov al,es:sin[bx] ; 256 times sine
- xor ah,ah
- dgsin2b:push dx
- mul yresval+6 ; times radius in y reference frame
- mov al,ah
- mov ah,dl ; divide by 256
- pop dx
- or di,di ; need a sign change?
- jz dgasin3 ; z = no
- neg ax ; flip it
- dgasin3:mov di,ax
-
- sub bx,90 ; bx is an index by now
- neg bx ; 90 - theta for cos
- cmp bx,90 ; at the limit?
- jne dgsin3a ; ne = no
- mov ax,256 ; set 16 bit value
- jmp short dgsin3b
- dgsin3a:mov al,es:sin[bx] ; 256 times cosine
- xor ah,ah
- dgsin3b:mul yresval+4 ; radius in x reference frame
- mov al,ah
- mov ah,dl ; divide by 256
- or si,si ; need a sign change?
- jz dgasin4 ; z = no
- neg ax
- dgasin4:mov si,ax
- pop es
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- dgasin endp
-
- ; Convert DG X coordinate in SI to PC screen coordinate in SI
- dg2pcx proc near
- push ax
- push cx
- push dx
- mov ax,si
- mov cx,xmax ; PC screen width - 8 dots
- add cx,7 ; right most dot
- imul cx
- mov cx,dgxmax ; DG width
- idiv cx ; AX gets PC dots across
- mov si,ax
- pop dx
- pop cx
- pop ax
- ret
- dg2pcx endp
-
- ; Convert DG Y coordinate in DI to PC screen coordinate in DI
- dg2pcy proc near
- push ax
- push cx
- push dx
- mov ax,di
- mov cx,ybot ; PC screen height
- sub cx,charhgt ; minus status line
- imul cx
- mov cx,dgymax ; DG height
- idiv cx
- mov di,ax ; ax has PC dots y dots
- pop dx
- pop cx
- pop ax
- ret
- dg2pcy endp
-
- ; Fill non-intersecting polygon whose vertices are specified as x,y word
- ; pairs in rdbuf+2. Word rdbuf has count of the pairs. Closure is implied.
- ; Coordinates are DG. Permit up to 255 vertices. PC text lines mar_top
- ; and mar_bot are in the last two words of rdbuf+2.
- dgpoly proc far
- push linepat ; save existing line pattern
- push si
- push di
- mov al,gfcol
- mov ah,gbcol
- push ax
- call remcursor ; remove text cursor
- test dgcross,1 ; is cross hair on?
- jz dgpoly1 ; z = no
- test dgcross,8 ; is cross hair invisible?
- jnz dgpoly1 ; nz = yes
- call crosdrawh ; remove present crosshairs
- call crosdrawv
- or dgcross,8 ; say cross is invisible
- dgpoly1:call dgsetcol ; set coloring
- mov bx,offset rdbuf ; list: count, pairs of x,y
- mov cx,[bx] ; get pair count
- add bx,2 ; start of x,y word pairs
- mov ax,ybot ; largest PC y value
- mov recty1,ax ; smallest PC y
- mov recty2,0 ; largest PC y
- dgpoly2:mov si,[bx] ; get DG x
- call dg2pcx ; convert to PC x coord
- mov [bx],si ; write back to list
- add bx,2
- mov di,[bx] ; get DG y
- cmp di,dgymax ; too tall?
- jbe dgpoly2a ; be = no
- mov di,dgymax ; clip to top
- dgpoly2a:call dg2pcy ; convert to PC y coord
- sub di,ybot
- add di,charhgt
- neg di ; invert for PC coord
- mov [bx],di ; write back to list
- cmp di,recty1 ; smaller?
- jae dgpoly3 ; ae = no
- mov recty1,di ; smallest PC y
- dgpoly3:cmp di,recty2 ; larger?
- jbe dgpoly4 ; be = no
- mov recty2,di ; largest PC y
- dgpoly4:add bx,2
- loop dgpoly2 ; do entire list
- ; top/bottom margin clipping
- mov ax,charhgt ; current char height
- mov dx,[bx] ; dx = mar_top
- mul dl ; dots to top of mar_top line
- cmp ax,recty1 ; is top margin higher (less)?
- jbe dgpoly4a ; be = yes, no top clipping
- mov recty1,ax ; clip to top margin
- dgpoly4a:mov ax,charhgt ; current char height
- mov dx,[bx+2] ; dx = mar_bot
- mul dl ; dots to bot of mar_bot line
- add ax,charhgt ; dots to bottom of mar_bot line
- dec ax
- cmp ax,recty2 ; is bot margin lower (more)?
- jae dgpoly4b ; ae = yes, no bottom clipping
- mov recty2,ax ; clip to bottom margin
- dgpoly4b:mov si,word ptr rdbuf+2 ; get start of list
- mov di,word ptr rdbuf+4
- mov [bx],si ; close the polygon
- mov [bx+2],di
-
- mov di,recty1 ; starting scan line, smallest PC y
- mov linepat,0ffffh ; solid lines
- dgpoly5:call dginter ; make list of intersections to decbuf
- cmp word ptr decbuf,2 ; any elements to be sorted/plotted?
- jb dgpoly7 ; b = no
- call dgsort ; sort x list in decbuf
- mov bx,offset decbuf+2
- dgpoly6:mov si,[bx] ; start x
- mov ax,[bx+2] ; end x
- mov cx,xmax ; right edge clipping test
- add cx,7 ; last dot to the right
- cmp ax,cx ; offscreen to the right?
- jbe dgpoly6a ; be = no
- mov ax,cx ; clip to right edge
- dgpoly6a:cmp si,cx ; this edge too?
- jbe dgpoly6b ; be = in bounds
- mov si,cx
- dgpoly6b:add bx,4 ; two words processed from list
- sub word ptr decbuf,2 ; two x elements taken care of
- cmp si,ax ; same place?
- je dgpoly6c ; e = yes
- push bx
- push di ; save reg
- mov bx,di ; end y, start y is in di
- mov cl,pixfor ; do just foreground dots
- call line ; draw the line
- pop di
- pop bx
- dgpoly6c:cmp word ptr decbuf,2 ; done all?
- jge dgpoly6 ; ge = no, do reset of list
- dgpoly7:inc di ; next scan line
- cmp di,recty2 ; at end of figure?
- jbe dgpoly5 ; be = no, do more scan lines
- pop ax
- mov gfcol,al
- mov gbcol,ah
- pop di
- pop si
- pop linepat ; restore line pattern
- ret
- dgpoly endp
-
- ; Provide PC x coordinate of intersections of a line with logical scan line
- ; DI. List of x,y pairs (nodes) is in rdbuf+2 et seq, count of them in rdbuf
- ; Writes x intersections to words in decbuf+2 et seq, count in decbuf.
- dginter proc near
- push dx
- mov si,offset decbuf+2 ; final x list
- mov word ptr decbuf,0 ; number detected for this scan line
- mov bx,offset rdbuf+2 ; index into x,y array
- mov cx,[bx-2] ; count of nodes (3 or more)
- dginter1:push cx ; see if line crosses this scan line
- mov ax,[bx+2] ; y[index]
- mov cx,[bx+2+4] ; y[index+1]
- cmp ax,cx
- jbe dginter2 ; be = ax is higher or same on screen
- xchg ax,cx ; make ax smaller than cx
-
- dginter2:cmp di,ax ; yscan vs y[index]
- jb dginter7 ; b = above this scan line
- cmp di,cx ; yscan vs y[index+1]
- ja dginter7 ; a = below this line
- mov ax,di ; yscan
- sub ax,[bx+2] ; ax = yscan - y[index]
- or ax,ax
- jnz dginter5 ; nz = not at a starting node
- push ax
- mov ax,[bx+2] ; current y[index]
- cmp bx,offset rdbuf+2+2 ; list start (wrap back situation)?
- jae dginter3 ; ae = no
- push bx
- mov bx,word ptr rdbuf ; count of x,y pairs
- shl bx,1
- shl bx,1 ; count pairs
- sub ax,word ptr rdbuf+2[bx-2] ; y[0] - y[maxindex-1]
- pop bx
- jmp short dginter4
- dginter3:sub ax,[bx-2] ; y[index] - y[index-1]
- dginter4:mov cx,[bx+2+4] ; y[index+1]
- sub cx,[bx+2] ; cx = delta y = y[index+1] - y[index]
- xor ax,cx ; compare with above slope
- pop ax
- jns dginter7 ; ns = same sign, do not count node
-
- dginter5:or ax,ax ; yscan - y[index]
- jz dginter6 ; z = at node, don't interpolate
- mov cx,[bx+4] ; x[index+1]
- sub cx,[bx] ; delta x = x[index+1] - x[index]
- imul cx
- mov cx,[bx+2+4] ; y[index+1]
- sub cx,[bx+2] ; cx = delta y = y[index+1] - y[index]
- idiv cx
- dginter6:add ax,[bx] ; plus x[index]
- mov [si],ax ; store in decbuf
- add si,2
- inc word ptr decbuf ; say counted a node
- dginter7:pop cx
- add bx,4 ; next x,y pair
- loop dginter1
- pop dx
- ret
- dginter endp
-
- ; Sort array of words decbuf, count then list of elements
- dgsort proc near
- push dx
- push si
- push di
- mov si,offset decbuf ; count + list
- mov cx,[si] ; count of items in list
- dec cx
- jcxz dgsort5
- add si,2 ; point to first element
- mov dx,si ; offset of first element
- add dx,cx ; plus count of elements
- add dx,cx ; offset of last element
- dgsort1:mov di,si ; first element
- add di,2 ; next element
- dgsort2:mov ax,[di] ; next x
- cmp ax,[si] ; current x
- jae dgsort3 ; ae = next is larger than current x
- xchg ax,[si] ; interchange elements
- xchg ax,[di]
- dgsort3:add di,2
- cmp di,dx ; finished last element?
- jbe dgsort2 ; be = no
- add si,2 ; next element of outer loop
- loop dgsort1
- dgsort5:pop di
- pop si
- pop dx
- ret
- dgsort endp
-
- ;;;;;;; EGA plot support routines
- psetupe proc near ; EGA setup for plotting
- push ax
- mov linelen,80 ; for y going down screen by pincy
- mov ax,segscn ; set es to screen memory segment
- mov es,ax
- mov ax,0205h ; mode: write mode 2
- call ega_gc
- mov ax,0003h ; assume writing bits directly
- test ccode,pixfor+pixbak ; direct foreground/background write?
- jnz psete2 ; nz = yes
- mov ax,1003h ; assume OR
- test ccode,pixor ; OR?
- jnz psete2 ; nz = yes
- mov ax,1803h ; assume XOR
- test ccode,pixxor ; inverting bits?
- jnz psete2 ; nz = yes
- mov ax,0803h ; then use AND
- psete2: call ega_gc ; set controller
- mov ax,80 ; compute starting point in regen buff
- mul di
- mov di,ax ; di = di * 80
- pop ax
- ret
- psetupe endp
-
- pincye proc near ; EGA inc y
- add di,linelen ; includes sign of deltay
- ret
- pincye endp
-
- pltega proc near ; EGA plot(x,y). x is in si, y is in di
- ror bp,1 ; rotate line pattern
- jc pltega1 ; c = a 1 bit to be plotted
- cmp ccode,pixfor+pixbak ; plot both 1's and 0's?
- je pltega1 ; e = yes
- ret ; else ignore the 0 bit
- pltega1:push bx
- push si
- push di
- mov bx,xmax
- add bx,7 ; last right dot
- cmp si,bx ; going out of bounds?
- ja pltega3 ; a = yes, omit the dot plot
- mov bx,si ; want si/8 for bytes along line
- shr si,1
- shr si,1
- shr si,1
- add di,si ; starting point in regen buffer
- and bx,0007h ; leave lower 3 bits for bit in byte
- mov bh,masktab[bx] ; 0-7 into bit mask in byte, x pos
- mov bl,ccode ; get line type code
- cmp bl,pixfor+pixbak ; plot both 1's and 0's?
- jne pltega2 ; ne = no
- mov bl,pixfor ; use foreground for ones
- test bp,80h ; bit is a one?
- jnz pltega2 ; nz = yes
- mov bl,pixbak ; use background for zeros
- pltega2:call ega_plt
- pltega3:pop di
- pop si
- pop bx
- ret
- pltega endp
-
- ;; Plot bit pattern in "fill" as 8 horizontal pixels, starting at x,y (si,di)
- ; and continuing across the line for cx pixels. psetupe has been called.
- bpltega proc near ; EGA plot(x,y). x is in si, y is in di
- push bx
- push cx
- push si
- push di
- mov bx,si ; want si/8 for bytes along line
- shr si,1
- shr si,1
- shr si,1
- add di,si ; starting byte in regen buffer
- ; di = offset in regen buffer
- and bl,7 ; get bit in byte (di = byte aligned)
- jz bplteg1 ; z = aligned already
- xchg bl,cl ; get shift to cl, low count to bl
- mov bh,fill ; 8-bit fill pattern
- mov al,bh ; get complement of pattern too
- not al
- shl bh,cl ; trim cl bits from the left
- shr bh,cl
- shl al,cl ; trim them from the right edge
- shr al,cl ; restore pattern
- xchg cl,bl ; put count back in cx
- add cl,bl ; add bits taken care of
- adc ch,0
- jmp short bplteg2 ; do this partial byte now
-
- bplteg1:mov bh,fill ; fill pattern
- mov al,bh ; make inverted pattern
- not al
- cmp cx,8 ; do all 8 bits?
- jae bplteg2 ; ae = yes
- push cx ; final byte fixup
- sub cl,8 ; cl = - (number of bits to omit)
- neg cl ; cl = number of bits to omit
- mov al,bh ; get complement of pattern too
- not al
- shr bh,cl ; trim them from the right edge
- shl bh,cl ; restore pattern
- shr al,cl ; trim them from the right edge
- shl al,cl ; restore pattern
- pop cx
- bplteg2:push ax
- cmp ccode,pixfor+pixbak ; do both fore and background?
- jne bplteg2a ; ne = no
- push bx
- mov bh,al ; get complemented pattern
- mov bl,pixbak ; write background
- call ega_plt
- pop bx
- bplteg2a:mov bl,ccode ; get line type code
- call ega_plt
- bplteg3:pop ax
- inc di ; next byte right
- sub cx,8 ; did these
- cmp cx,0 ; anything left to do?
- jg bplteg1 ; a = yes, repeat
- pop di
- pop si
- pop cx
- pop bx
- ret
- bpltega endp
-
- ;;;;;;;; CGA plot support routines
- ; The CGA graphics memory mapping in mode 6 (640 by 200) is 8 dots per byte,
- ; left most dot in the high bit, 80 bytes per scan line, scan line segments
- ; alternating between 0b800h (even lines 0, 2, ...) and 0ba00h (odd lines).
- psetupc proc near ; CGA setup for plotting
- push ax
- push cx
- mov linelen,80 ; 80 bytes per scan line
- mov cx,segscn
- mov es,cx
- mov cx,di ; save copy of di, start y line
- ; compute starting point in regen buff
- shr di,1 ; half the lines in each bank
- mov ax,80 ; 80 bytes per line
- mul di
- mov di,ax ; di = di * 80 / 2
- test cx,1 ; even or odd line
- jz psetc1 ; z = even
- add di,2000h ; offset to odd bank (seg 0ba00h)
- psetc1: and di,3fffh
- pop cx
- pop ax
- ret
- psetupc endp
-
- pincyc proc near ; CGA inc y
- cmp linelen,0 ; increasing or decreasing y?
- jl pinyc2 ; l = decreasing
- cmp di,2000h ; in upper bank now?
- jb pinyc1 ; b = no, in lower bank
- add di,linelen ; add a line
- pinyc1: add di,2000h ; switch banks
- and di,3fffh ; roll over address
- ret
- pinyc2: cmp di,2000h ; in upper bank now?
- jae pinyc4 ; ae = yes
- add di,linelen ; subtract a line
- pinyc4: add di,2000h ; switch banks
- and di,3fffh ; roll over address
- ret
- pincyc endp
-
- pltcga proc near ; CGA plot(x,y). x is in si, y is in di
- ror bp,1 ; rotate line pattern
- jc pltcg6 ; c = 1 bit to be plotted
- cmp ccode,pixfor+pixbak ; plot both 1's and 0's?
- je pltcg6 ; e = yes
- ret
- pltcg6: push bx ; used for HGA and Wyse plots also.
- push si
- push di
- mov bx,xmax
- add bx,7 ; last right dot
- cmp si,bx ; going out of bounds?
- ja pltcg3 ; a = yes, omit the dot plot
- mov bx,si ; want si/8 for bytes along line
- shr si,1
- shr si,1
- shr si,1
- add di,si ; starting point in regen buffer
- and bx,0007h ; leave lower 3 bits for bit in byte
- ; di = offset in regen buffer
- mov bh,masktab[bx] ; 0-7 into bit mask in byte. x position
- mov bl,ccode ; get line type code
- cmp bl,pixfor+pixbak ; plot both 1's and 0's?
- jne pltcg7 ; ne = no
- mov bl,pixfor ; use foreground for ones
- test bp,80h ; bit is a one?
- jnz pltcg7 ; nz = yes
- mov bl,pixbak ; use background for zeros
- pltcg7:
- test bl,pixfor+pixor ; draw in foreground color or OR?
- jz pltcg1 ; z = no
- test bl,pixor ; OR?
- jnz pltcg5 ; nz = yes
- test gfcol,7 ; is foreground dark?
- jz pltcg4 ; z = yes, punch a hole
- pltcg5: or es:[di],bh ; drawn
- jmp short pltcg3
- pltcg1: test bl,pixbak ; draw in background (erase)?
- jz pltcg2 ; z = no
- test gbcol,7 ; is background light?
- jnz pltcg5 ; nz = yes
- pltcg4: not bh ; invert the bit
- and es:[di],bh ; erase the dot
- jmp short pltcg3
- pltcg2: xor es:[di],bh ; xor in this color
- pltcg3: pop di
- pop si
- pop bx
- ret
- pltcga endp
-
- ; Plot bit pattern in fill as 8 horizontal pixels, starting at x,y (si,di)
- ; and continuing across the line for cx pixels. psetupc has been called.
- bpltcga proc near ; CGA plot(x,y). x is in si, y is in di
- push bx ; used for HGA and Wyse plots also.
- push cx
- push si
- push di
- mov bx,si ; want si/8 for bytes along line
- shr si,1
- shr si,1
- shr si,1
- add di,si ; starting byte in regen buffer
- ; di = offset in regen buffer
- and bl,7 ; get bit in byte (di = byte aligned)
- jz bpltcg5 ; z = aligned already
- xchg bl,cl ; get shift to cl, low count to bl
- mov bh,fill ; 8-bit fill pattern
- shl bh,cl ; trim cl bits from the left
- shr bh,cl
- push cx
- mov al,0ffh ; 1's are original bits to be saved
- sub cl,8 ; max field width is 8 bits
- neg cl ; 8-number of bits trimmed from left
- shl al,cl ; al now holds save-field bit pattern
- pop cx
- xchg cl,bl ; put count back in cx
- add cl,bl ; add bits taken care of
- adc ch,0
- jmp short bpltcg4 ; do this partial byte now
-
- bpltcg5:mov bh,fill ; fill pattern
- xor al,al ; assume saving no bits
- cmp cx,8 ; do all 8 bits?
- jae bpltcg4 ; ae = yes
- push cx ; final byte fixup
- mov al,0ffh ; 1's are original bits to be saved
- shl al,cl
- shr al,cl ; al now holds save-field bit pattern
- sub cl,8 ; cl = - (number of bits to omit)
- neg cl ; cl = number of bits to omit
- shr bh,cl ; trim them from the right edge
- shl bh,cl ; restore pattern
- pop cx
- bpltcg4:mov bl,ccode ; get line type code
- cmp bl,pixfor+pixbak ; set both fore and background?
- jne bpltcg9 ; ne = no
- test gfcol,7 ; is foreground dark?
- jnz bpltcg8 ; nz = no
- not bh ; invert the bit pattern
- or bh,al ; set bits to be saved
- sub bh,al ; trim off saved bits from this field
- bpltcg8:mov ah,es:[di] ; get contents of memory cell
- and ah,al ; preserve bit field given by al
- or bh,ah ; mask in saved bits
- mov es:[di],bh ; write the byte
- jmp short bpltcg3 ; done
- bpltcg9:test bl,pixfor+pixor ; draw in foreground?
- jz bpltcg1 ; z = no
- test bl,pixor ; OR?
- jnz bpltcg7 ; nz = yes
- test gfcol,7 ; is foreground dark?
- jz bpltcg6 ; z = yes, punch a hole
- bpltcg7:or es:[di],bh ; drawn
- jmp short bpltcg3
- bpltcg1:test bl,pixbak ; draw as background (erase)?
- jz bpltcg2 ; z= do not draw as background (erase)
- test gbcol,7 ; is background light?
- jz bpltcg6 ; z = no
- or es:[di],bh ; drawn
- jmp short bpltcg3
- bpltcg6:not bh
- and es:[di],bh ; erase background dots (0's)
- jmp short bpltcg3
- bpltcg2:xor es:[di],bh ; xor with these dots
- bpltcg3:inc di ; next byte right
- sub cx,8 ; did these
- cmp cx,0 ; anything left to do?
- jg bpltcg5 ; a = yes, repeat
- pop di
- pop si
- pop cx
- pop bx
- ret
- bpltcga endp
-
- ;;;;;;; Wyse-700 plot support routines
- ; The Wyse graphics memory map in mode 0D3h (1280 by 800) is 8 dots per byte,
- ; left most dot in the high bit, 160 bytes per scan line, scan line segments
- ; sequence as 0a000h even lines, and same for odd lines
- psetupw proc near ; Wyse setup for plotting
- push ax
- push cx
- push dx
- mov linelen,160 ; for y going down screen by incy
- mov ax,segscn ; base segment of display memory
- mov es,ax
- mov cx,di ; save copy of di, start y line
- ; compute starting point in regen buff
- shr di,1 ; half the lines in each bank
- mov ax,160
- mul di
- mov di,ax ; di = di * 160 / 2
- mov dx,wymode
- shr cx,1 ; compute bank from 1 lsb of line num
- jnc psetw2 ; nc = it is in bank 0 (0b000h)
- mov ax,wybodd ; select odd bank
- out dx,al
- jmp short psetw3
- psetw2: mov ax,wybeven ; select even bank
- out dx,al
- psetw3: mov bnkchan, al ; bank has changed
- pop dx
- pop cx
- pop ax
- ret
- psetupw endp
-
- ;
- ; Wyse-700 has two banks. Line 0, 2, 4 ... are in bank 0, and 1, 3, 5 ... are
- ; in bank 1. Lines 0 and 1 have same addresses, lines 2 and 3 have same
- ; addresses etc. We have to change bank every time Y changes but we
- ; have to count new address only after two Y-value changes. Variable
- ; bnkchan is a flag for us to know into which bank to write.
- ;
- pincyw proc near ; Wyse inc y, step offset of line
- push ax
- push dx
- mov dx,wymode ; Wyse conrol register
- mov al,wybeven ;
- cmp bnkchan,wybeven ; was last write into even bank ?
- jne pincywe ; ne = no
- mov al,wybodd ; yes, set ready for odd bank
- out dx,al ;
- mov bnkchan,al ; set to odd
- jmp short pincywo
- pincywe:mov al,wybeven ; set ready foe even bank
- out dx,al ; select it
- mov bnkchan,al ; set to odd
- pincywo:cmp linelen,0 ; increasing y?
- jg pinyw2 ; g = yes
- cmp al,wybeven ; from high (1) to low (0) bank ?
- je pinyw4 ; e = yes
- add di,linelen ; no, add a line
- jmp short pinyw4
- pinyw2: cmp al,wybodd ; from low (0) to high (1) bank ?
- je pinyw4 ; e = yes
- add di,linelen ; no, add a line
- pinyw4: and di,0ffffh ; roll over address
- pop dx
- pop ax
- ret
- pincyw endp
-
- ;;;;;;; HGA plot support routines
- ; The HGA graphics memory mapping in mode 255 (720 by 348) is 8 dots per byte,
- ; left most dot in the high bit, 90 bytes per scan line, scan line segments
- ; sequence as 0b000h, 0b200h, 0b400h, 0b800h for lines 0-3 and repeat 90 bytes
- ; higher for the rest.
- psetuph proc near ; HGA setup for plotting
- push ax
- push cx
- mov linelen,90 ; for y going down screen by incy
- mov ax,segscn ; base segment of display memory
- mov es,ax
- mov cx,di ; save copy of di, start y line
- ; compute starting point in regen buff
- shr di,1 ; quarter the lines in each bank
- shr di,1
- mov ax,90
- mul di
- mov di,ax ; di = di * 90 / 4
- and cx,3 ; compute bank from 2 lsb of line num
- jcxz pseth2 ; z means it is in bank 0 (0b000h)
- pseth1: add di,2000h ; add offset for each bank
- loop pseth1 ; do cx times
- pseth2: pop cx
- pop ax
- ret
- psetuph endp
-
- pincyh proc near ; HGA inc y, step offset of line
- cmp linelen,0 ; increasing y?
- jg pinyh2 ; g = yes
- cmp di,2000h ; in lowest for four banks?
- ja pinyh1 ; a = no
- add di,linelen ; yes, add a line
- pinyh1: add di,6000h ; move back by adding a lot
- and di,7fffh ; roll over address
- ret
- pinyh2: cmp di,6000h ; in top most bank?
- jb pinyh4 ; b = no
- add di,linelen ; yes, first add a line
- pinyh4: add di,2000h ; switch to next bank
- and di,7fffh ; roll over address
- ret
- pincyh endp
-
- ;;;;;;; AT&T-Olivetti, Toshiba, VAXmate Graphics Adapter plot support routines
- ; The graphics memory mapping in 640 by 400 mode is 8 dots per byte,
- ; left most dot in the high bit, 80 bytes per scan line, scan line segments
- ; sequence as 0b800h, 0ba00h, 0bc00h, 0be00h for lines 0-3 and repeat 80 bytes
- ; higher for the rest. Use Hercules line incrementing (inc y) and CGA dot
- ; writing. This is a monographic display.
- psetupo proc near ; setup for plotting
- push ax
- push cx
- mov linelen,80 ; for y going down screen by incy
- mov ax,segscn ; base segment of display memory
- mov es,ax
- mov cx,di ; save copy of di, start y line
- ; compute starting point in regen buff
- shr di,1 ; quarter the lines in each bank
- shr di,1
- mov ax,80
- mul di
- mov di,ax ; di = di * 80 / 4
- and cx,3 ; compute bank from 2 lsb of line num
- jcxz pseto2 ; z means it is in bank 0 (0b800h)
- pseto1: add di,2000h ; add offset for each bank
- loop pseto1 ; do cx times
- pseto2: pop cx
- pop ax
- ret
- psetupo endp
-
- ;;;;;;;; Monochrome, simulate dots with text char
- psetupm proc near
- mov linelen,1 ; 80 characters but one line
- ret
- psetupm endp
-
- pltmon proc near ; Monochrome dot plot
- mov x_coord,si ; put dot at row=di, col=si, PC Coord
- mov y_coord,di
- push ax
- mov al,'+'-' ' ; our dot character
- call mputc ; display text char
- pop ax
- ret
- pltmon endp
-
- ; Plot bit pattern in fill as 8 horizontal pixels, starting at x,y (si,di)
- ; and continuing across the line for cx pixels. Destroys CX.
- bpltmon proc near ; Mono plot(x,y). x is in si, y is in di
- jmp pltmon ; a dummy for the present
- bpltmon endp
-
- pincym proc near ; Monochrome inc y
- add di,linelen ; includes sign
- ret
- pincym endp
-
- ; GPUTC - a routine to send text characters from font to true graphics boards
- ; such as EGA, Hercules or CGA. Char is in al. Drawing routine ptr is gcplot.
- gputc proc near
- push bx ; first save some registers
- push cx
- push es
- push di
- mov bl,al ; now BL has char to be displayed
- xor bh,bh
- ; set board mode
- mov di,y_coord ; get current y coord (char bottom)
- inc di
- sub di,charhgt ; start charlines-1 lines higher
- jnc gputc3 ; nc = ok
- mov di,charhgt
- dec di
- mov y_coord,di ; reset scan line indicator
- xor di,di ; move up to first line
- gputc3: call psetup ; enter with di=line number, sets es:di to start of
- ; line in regen buffer and sets byte-wide plot mode
- mov si,x_coord ; si has x-axis in PC screen coord
- mov cx,charhgt ; bytes (scan lines) to transfer
- call gcplot ; call character plot routine
- call incx ; move to next char position
- pop di
- pop es
- pop cx
- pop bx
- ret
- gputc endp
-
- putctrl proc near ; CONTROL CHARS = cursor movement
- cmp al,FF ; formfeed?
- jne putct0 ; ne = no
- jmp TEKCLS ; FF clears the screen
-
- putct0: cmp al,BS ; BS? sends (logical) cursor back one
- jne putct2 ; ne = no, try next
- mov ax,charwidth ; char width
- sub x_coord,ax ; delete charwidth dots (move left)
- jnc putct1 ; nc = ok
- mov x_coord,0 ; limit to left margin
- putct1: cmp bscontrol,0 ; non-destructive backspace?
- je putctx ; e = yes
- push x_coord ; destructive backspace
- mov al,' ' ; a space to be written
- call gputc ; write it
- pop x_coord ; restore cursor
- ret
-
- putct2: cmp al,TAB ; tabs move forward one char position
- jne putct4 ; ne = not a tab
- ;;; OR X_COORD,7*8
- jmp incx ; let incx move cursor right one col
-
- putct4: cmp al,CR ; <CR> means go to beginning of line
- jne putct5
- mov x_coord,0 ; zero the x coordinate
- ret
-
- putct5: cmp al,LF ; <LF> means go down 8 pixels (1 line)
- jne putct7 ; ne = not LF
- mov ax,charhgt
- add y_coord,ax ; border managed by outscrn and incx
- ret
-
- putct7: cmp al,VT ; <VT> move up screen 1 line (8 pixels)
- jne putctx
- mov ax,charhgt ; character height
- sub y_coord,ax ; subtract one line (charhgt pixels)
- jnc putctx ; nc = space left
- mov y_coord,ax ; else set to top of screen
- putctx: ret
- putctrl endp
-
- mputc proc near ; MONO put char in AL via Bios
- push bx ; updates x_coord,y_coord with
- push cx ; new cursor position
- push dx
- xor ah,ah ; marker for cursor setting not needed
-
- mputc1: push ax ; save char and marker
- mov cl,3 ; char cell is 8 x 8 dots
- mov ax,x_coord ; get resulting cursor PC positions
- shr ax,cl
- mov dl,al ; column
- mov ax,y_coord
- inc ax
- sub ax,charhgt ; minus (charhgt-1) dots
- jnc mputc2 ; nc = non-negative
- mov ax,charhgt ; else start at the top
- inc ax
- mov y_coord,ax ; here too
- mputc2: shr ax,cl
- mov dh,al ; row
- mov ah,2 ; set cursor to x_coord,y_coord
- xor bh,bh ; page 0
- int screen
- pop ax
- or ah,ah ; write a char in al?
- jnz mputcx ; nz = no
- mov ah,09h ; write char at cursor postion
- mov cx,1 ; just one char
- xor bh,bh ; page 0
- mov bl,gfcol ; foreground coloring
- int screen
- inc dl ; next column
- mov ah,2 ; set real cursor ahead of last char
- int screen
- call incx ; move logical cursor
- mputcx: pop dx
- pop cx
- pop bx
- ret
- mputc endp
-
- incx proc near ; move the logical cursor right
- mov ax,xmax
- add ax,8
- sub ax,charwidth ; last column+1
- cmp ax,x_coord ; beyond right most column?
- jae incx1 ; ae = no
- mov x_coord,ax ; set up for wrap
- ret
- incx1: mov ax,charwidth
- add x_coord,ax ; shift the (logical) cursor right
- ret ; one character cell
- incx endp
-
- ; Character plot routine. Enter with BL holding char code
- ; cx = number of bytes in char font, es:di = screen memory. Worker for gputc.
- ; ccode: pixbak=plot in backgrd colors, pixfor=foregrd, pixxor=xor with screen
- gcplot proc near
- mov al,ccode ; save original ccode and fill pattern
- mov ah,fill
- push ax
-
- push cx
- push ds
- push es
- push si
- push di
- mov di,seg dotbuf ; destination buffer for font dots
- mov es,di
- mov di,offset dotbuf
- xor bh,bh
- test bl,80h ; high bit set?
- jz gcplot1 ; z = no
- lds si,fontrptr ; use GRight font set
- and bl,not 80h ; strip high bit now
- jmp short gcplot2
- gcplot1:lds si,fontlptr ; use GLeft font set
- gcplot2:mov ax,cx ; char height (bytes per char)
- mul bl ; bytes into table for char in bl
- add si,ax ; offset into font by char
- cld
- rep movsb ; copy font dots to dotbuf
- pop di
- pop si
- pop es
- pop ds
- pop cx
- xor bx,bx ; index into dotbuf
- gcplot3:push bx
- push cx
- mov al,dotbuf[bx] ; get 8 bits from font
- mov cx,si ; x-axis in PC screen coordinates
- and cl,0111b ; bit in byte across the screen
- ror al,cl ; rotate pattern for gfplot filling
- mov cx,charwidth ; do charwidth bits on the line
- mov fill,al ; use "fill" as fill pattern
- call gfplot ; fill a scan line for cx bits
- call pincy ; next scan line (linelen is preset)
- pop cx
- pop bx
- inc bx ; next byte of char pattern
- loop gcplot3
- pop ax
- mov ccode,al ; recover variables
- mov fill,ah
- ret
- gcplot endp
-
- ; routines to manipulate ega graphics controller and mode register
- ; command code in al, value in ah - destroys al and dx
-
- ega_gc proc near ; ega graphics controller
- mov dx,3ceh
- out dx,al ; output command code
- inc dx ; dx is now data port
- mov al,ah ; get value to al
- out dx,al ; output value
- ret
- ega_gc endp
- ega_md proc near ; ega mode controller
- mov dx,3c4h
- out dx,al ; output command code
- inc dx ; dx is now data port
- mov al,ah ; get value to al
- out dx,al ; output value
- ret
- ega_md endp
-
- ; Plot eight pixels using an EGA board
- ; Enter with ES:[DI] pointing to screen address of byte,
- ; bh has pattern of bits to be set, bl has attributes:
- ; pixbak = draw in background color, pixfor = draw in foreground color,
- ; pixor = OR with foreground color, pixxor = XOR with foreground color.
- ; registers preserved
- ; Note: this function operates on 8 pixels. One bits in bh select pixels to
- ; be changed, bl determines which color planes will be affected for every
- ; selected pixel.
- ega_plt proc near
- push ax
- push dx
- mov dx,3ceh ; (ega_gc) unprotect the bit positions
- mov al,8 ; command to set bit mask register
- out dx,al ; output command code
- inc dx ; dx is now data port
- mov al,bh ; get pixels to be modified (1's)
- out dx,al ; output value (end of ega_gc)
- pop dx
-
- mov ah,gfcol ; foreground color bit planes
- ega1: test bl,pixfor+pixor ; write foreground or OR?
- jnz ega3 ; nz = yes
- mov ah,gbcol ; background color bit planes
- test bl,pixbak ; write in background coloring?
- jnz ega3 ; nz = yes
- mov ah,0fh ; xor, touch each bit plane
- ega3: mov al,es:[di] ; latch byte
- mov es:[di],ah ; merge with untouched bits
- pop ax
- ret
- ega_plt endp
-
- ; Presence test for Wyse-700: info in B000h and B800h are supposed to be equal
- chkwyse proc near
- push es
- push ds
- mov ax,0b800h ; CGA segment
- mov es,ax
- mov ax,0b000h ; Mono segment
- mov ds,ax
- mov ch,byte ptr es:[0] ; CGA seg
- mov cl,byte ptr ds:[0] ; Mono seg
- push cx ; save original contents
- mov byte ptr ds:[0],ch ; copy CGA to Mono
- cmp byte ptr ds:[0],ch ; if different then not Wyse
- jne chkwys1 ; ne = not Wyse
- not byte ptr es:[0] ; change CGA contents
- not ch ; and original pattern
- cmp ch,byte ptr ds:[0] ; if different then not Wyse
- jne chkwys1 ; ne = not Wyse
- pop cx
- mov byte ptr es:[0],ch ; restore CGA
- mov byte ptr ds:[0],cl ; restore Mono
- pop ds
- pop es
- clc
- ret
-
- chkwys1:pop cx
- mov byte ptr es:[0],ch ; restore CGA
- mov byte ptr ds:[0],cl ; restore Mono
- pop ds
- pop es
- stc
- ret
- chkwyse endp
- ;
- ; routine to set Wyse-700 board to graphics mode - 1280 * 800 & cls
- ;
- WYGRAF PROC NEAR
- push ax
- push bx ; save used registers
- push cx
- push dx
- push di
- xor al,al
- mov dx,wystoff ; map video memory offset to zero
- out dx,al ;
- mov dx,wystseg ; map video memory segment to zero
- out dx,al ;
- mov ax,segwyse ; set es to Wyse start segment
- mov es,ax ;
- mov al,wybeven ; graph mode - even bank
- mov dx,wymode ; Wyse mode control register
- out dx,al ; select even bank
- cld
- xor ax,ax ; zero ax
- xor di,di ; start from zero
- mov cx,0ffffh ; clear 10000h bytes, whole even bank
- rep stosb ; store blanking char in whole screen
- mov al,wybodd ; graph mode - odd bank
- mov dx,wymode ; select it
- out dx,al ;
- xor ax,ax ; zero ax
- xor di,di ;
- mov cx,0ffffh ; clear 10000h bytes, whole odd bank
- rep stosb ; store blanking char in whole screen
- mov bnkchan, 0 ; assume bank 0
- pop di ; restore regs
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- WYGRAF ENDP
-
- ; routine to set Hercules card to graphics mode - both pages are enabled
-
- HGRAF PROC NEAR
- push ax
- push bx ; save used registers
- push cx
- push si
- mov al,grph ; graph mode
- lea si,gtable ; requires graphics table
- xor bx,bx
- mov cx,4000h ; clear 4000h words
- test gbcol,7 ; any (light) background color bits?
- jz hgraf1 ; z = no, we are ok
- dec bx ; light background, set all the bits
- hgraf1: call setmd ; and set the mode
- pop si
- pop cx
- pop bx
- pop ax
- ret
- HGRAF ENDP
-
- ; set Hercules card to text mode
- HTEXT PROC NEAR
- push ax
- push bx
- push cx
- push si
- mov al,text ; text mode
- lea si,ttable ; requires text table
- mov bx,0720h ; blank value (space, white on black)
- mov cx,2000 ; whole screen to clear (80*25)
- call setmd ; set the mode
- pop si
- pop cx
- pop bx
- pop ax
- ret
- HTEXT ENDP
-
- ; Hercules mode set - called from HTEXT and HGRAF
- SETMD PROC NEAR
- push dx
- push ax
- mov dx,config ; configuration port
- mov al,genable ; allow graphics mode to be set
- out dx,al
- pop ax
- push ax
- push cx ; save count
- mov dx,cntrl ; control port
- out dx,al ; set to text or graphics
- mov dx,index ; send 12 bytes from table to 6845
- mov cx,12 ; number of registers to load
- xor ah,ah ; start with register 0 of 6845
- cld
- setmd1: jmp $+2 ; small pause for hardware
- mov al,ah ; ah is counter
- out dx,al ; set register
- inc dx ; point to data port
- lodsb ; get next byte in table
- jmp $+2 ; small pause for hardware
- out dx,al ; and send to 6845
- inc ah ; next register
- dec dx ; point to register port
- loop setmd1 ; and continue 'til cx=0
- pop cx ; recover count
- cld
- push di
- push es
- mov ax,segscn ; start of screen
- mov es,ax
- xor di,di
- mov ax,bx ; get blanking character
- rep stosw ; store blanking char in whole screen
- pop es
- pop di
- mov dx,cntrl ; now to re-enable screen
- pop ax ; get mode
- or al,scrn_on ; enable screen
- out dx,al
- pop dx
- ret
- SETMD ENDP
-
- teksave proc near ; saves graphics screen from page 0 to page 1
- mov temp,1 ; say saving from video to storage
- push si
- push di
- cmp gpage,0 ; only graphics page 0 on display board?
- je teksavx ; e = yes, no saving possible here
- mov si,segscn ; segment (!) of current screen
- cmp graph_mode,ega
- je teksav1
- cmp graph_mode,monoega
- je teksav1
- cmp graph_mode,colorega
- je teksav1
- cmp graph_mode,hercules
- je teksav2
- jmp short teksavx ; else nothing
- teksav1:mov di,segega+800h ; EGA page 1 screen segment
- call egasr ; call common save/restore code
- jmp short teksavx
- teksav2:mov di,seghga+800h ; Hercules page 1 screen segment
- call hgasr ; call common save/restore code
- teksavx:pop di
- pop si
- ret
- teksave endp
-
- tekrest proc near ; restores graphics screen in page 1 to page 0
- mov temp,-1 ; say restoring storage to video
- push si
- push di
- cmp gpage,0 ; only graphics page 0 on display board?
- jne tekres0 ; ne = no, more so work to do here
- call tekcls1 ; else clear the screen to color it
- jmp short tekresx ; and exit
- tekres0:mov di,segscn ; segment (!) of new graphics screen
- cmp graph_mode,ega
- je tekres1
- cmp graph_mode,monoega
- je tekres1
- cmp graph_mode,colorega
- je tekres1
- cmp graph_mode,hercules
- je tekres2
- jmp short tekresx ; else nothing
- tekres1:mov si,segega+800h ; segment of EGA page 1
- call egasr ; call common save/restore code
- jmp short tekresx
- tekres2:mov si,seghga+800h ; segment of Hercules page 1
- call hgasr ; call common save/restore code
- tekresx:pop di
- pop si
- ret
- tekrest endp
-
- egasr proc near ; common code for Tek ega save/restore ops
- push ax
- push cx
- push dx
- mov ax,0f00h ; enable 4 plane set/resets
- call ega_gc ; set controller
- mov ax,0f01h ; enable Set/Reset register
- call ega_gc
- mov ax,0f02h ; set color compare register for 4 planes
- call ega_gc
- mov ax,0905h ; set mode reg: write latches, read mode
- call ega_gc
- mov ax,0ff02h ; enable all planes
- call ega_md
- mov cx,ybot ; last scan line
- inc cx ; number of scan lines
- mov ax,80 ; bytes per scan line
- mul cx
- mov cx,ax
- push es ; save es
- push ds ; save ds
- call gsems ; try to store to/from expanded memory
- jnc egasr1 ; nc = success
- mov es,di ; destination, set es to video memory
- mov ds,si ; source, set ds to video memory
- xor si,si ; clear offset fields
- xor di,di
- cld ; byte moves for ega adaptor
- rep movsb ; copy from page (ds:si) to page (es:di)
- egasr1: pop ds ; recover ds
- pop es ; and other registers
- call gcreset ; reset controller
- pop dx
- pop cx
- pop ax
- ret
- egasr endp
-
- ; Transfer video to/from EMS memory for EGA/VGA boards
- ; SI is source seg, DI is dest seg, CX is pixel count, temp > 0 for saving
- ; to ems, temp < 0 for saving to video memory.
- ; Return carry set if failure, else carry clear
- gsems proc near
- cmp emsrbhandle,0 ; have rollback in expanded memory?
- jg gsems1 ; g = yes, else use video memory
- stc
- ret
- gsems1: cmp cx,emsbytes ; same as last time used?
- je gsems4 ; e = yes, use present allocation
- mov ah,emsrelease ; release handle and memory
- mov dx,emsgshandle ; handle
- or dx,dx ; is handle valid (>= 0)?
- jl gsems1a ; l = no
- int emsint ; ems interrupt
- gsems1a:mov emsgshandle,-1
- cmp temp,0 ; is this a restore operation?
- jl gsems1b ; l = yes, absent ems screen
- mov emsbytes,cx ; remember qty pixel bytes
- mov ax,cx
- add ax,1000h-1 ; one ems page size/4 - 1 byte
- mov cl,12 ; bits to slide
- shr ax,cl ; divide by 4000h bytes per ems page
- mov cx,ax ; save desired page count
- mov ah,emsgetnpgs ; get number 16KB pages free
- int emsint ; to bx
- cmp bx,cx ; ((640x480/8)*4)=153,6400B = 10 pages
- jae gsems2 ; ae = have enough space
- gsems1b:mov emsbytes,0
- call gcreset ; reset controller
- call tekcls ; clear screen
- clc ; fake success with fresh screen
- ret
- gsems2: mov bx,cx ; number of pages wanted
- mov ah,emsalloc ; allocate bx pages
- int emsint
- or ah,ah ; successful?
- jz gsems3 ; z = yes
- mov emsbytes,0
- stc
- ret
- gsems3: mov emsgshandle,dx ; returned handle
- mov ah,emsgetseg ; get segment of page frame
- int emsint ; to bx
- mov emsseg,bx ; save here
- mov ah,emsgetver ; get EMS version number
- int emsint ; to al (high=major, low=minor)
- cmp al,40h ; at least LIM 4.0?
- jb gsems4 ; b = no, so no name for our area
- push si
- push di
- mov si,offset emsgsname ; point to name for graphics area
- mov di,offset emsgsname+6 ; add digits
- mov ax,emsgshandle
- call dec2di ; write to handle name
- mov byte ptr [di],' ' ; must end in a space
- mov dx,emsgshandle
- mov ax,emssetname ; set name for handle from ds:si
- int emsint
- pop di
- pop si
-
- gsems4: call gcreset ; reset controller
- mov ax,0005h ; read mode 0, write mode 0
- call ega_gc
- cmp temp,0 ; get direction of saving/restoring
- jl gsems7 ; l = restore (storage to video)
- ; Save (video to ems)
- mov ax,emsseg ; get ems segment
- mov es,ax ; set destination
- mov ds,si ; save (video to storage)
- xor bx,bx ; page 0
- call getpage ; get EMS page bx
- xor di,di ; start of page frame
- mov cx,4 ; plane loop
-
- gsems4a:push cx ; save plane counter
- call selplane ; select plane in cl (1..4)
- push ds
- mov cx,seg emsbytes
- mov ds,cx
- mov cx,emsbytes ; pixel counter
- pop ds
- xor si,si ; start of video buffer
-
- gsems5: mov ax,cx ; save total byte count
- cmp cx,dx ; larger than one page?
- jbe gsems6 ; be = no
- mov cx,dx ; one page
- gsems6: sub ax,cx ; ax is bytes remaining to do
- sub dx,cx ; bytes to be used in EMS page
- cld
- rep movsb ; video to ems page
- mov cx,ax ; pixels to do
- or dx,dx ; EMS bytes left in page?
- jnz gsems6a ; nz = yes
- inc bx ; next ems page
- call getpage
- xor di,di ; start of page
- gsems6a:inc cx ; inc for loop dec below
- loop gsems5 ; do all pixels
-
- pop cx ; recover plane counter
- loop gsems4a ; do next plane
- clc
- ret
- ; copy from ems to video
- gsems7: mov es,di ; destination segment (video)
- mov ax,emsseg ; get ems segment
- mov ds,ax ; set source
- xor bx,bx ; page
- call getpage ; get EMS page bx
- xor si,si ; start of frame buffer
- mov cx,4 ; plane counter
-
- gsems7a:push cx ; save plane counter
- call selplane ; select plane in cl (1..4)
- push ds
- mov cx,seg emsbytes
- mov ds,cx
- mov cx,emsbytes ; pixel counter
- pop ds
- xor di,di ; start of video buffer
-
- gsems8: mov ax,cx ; save total byte count
- cmp cx,dx ; larger than this page can hold?
- jbe gsems9 ; be = no
- mov cx,dx ; use value available
- gsems9: sub ax,cx ; ax is bytes remaining to do
- sub dx,cx ; bytes to be used in EMS page
- cld
- rep movsb ; EMS page to video
- mov cx,ax ; pixels to do
- or dx,dx ; EMS bytes left in page?
- jnz gsems9a ; nz = yes
- inc bx ; next ems page
- call getpage
- xor si,si ; start of page
- gsems9a:inc cx ; inc for loop dec below
- loop gsems8 ; do all pixels
-
- pop cx ; recover plane counter
- loop gsems7a ; do next plane
- clc
- ret
- gsems endp
-
- ; Get EMS logical page BX into EMS physical page 0
- ; Returns in DX the number of free bytes (16KB). Modifies AX
- getpage proc near
- push ds
- mov ax,seg emsgshandle
- mov ds,ax
- mov ah,emsmapmem ; map logical page in bx
- xor al,al ; to physical page zero
- mov dx,emsgshandle ; our ems handle
- int emsint
- mov dx,4000h ; bytes in this page
- pop ds
- ret
- getpage endp
-
- ; Select EGA video plane in cl (1..4) for r/w
- selplane proc near
- push cx
- push dx
- dec cl ; count planes as 0..3
- and cl,3 ; range bound (planes 0..3)
- mov ah,cl ; binary value for read map select
- mov al,4 ; read map select register
- call ega_gc ; set read map plane
- mov ah,1 ; convert to plane number
- shl ah,cl ; convert plane number to bit position
- mov al,2 ; map mask register
- call ega_md ; select plane for writing
- pop dx
- pop cx
- ret
- selplane endp
-
- ; Reset EGA board prior to video<->ems copying
- gcreset proc near
- push ax
- push dx
- mov ax,0ff08h ; bit mask reg to all 8 bits
- call ega_gc
- mov ax,0003h ; direct write
- call ega_gc
- mov ax,0004h ; read map select to map 0
- call ega_gc
- mov ax,0000h ; set/reset latches
- call ega_gc
- mov ax,0001h ; set/reset enable, disable
- call ega_gc
- mov ax,0f02h ; enable all planes for write
- call ega_md
- pop dx
- pop ax
- ret
- gcreset endp
-
- hgasr proc near ; Hercules save restore screen
- push cx
- mov cx,4000h ; number of words to move
- push es ; save es
- push ds ; save ds
- mov es,di ; destination, set es to video memory
- mov ds,si ; source, set ds to video memory
- xor si,si ; clear offset fields
- xor di,di
- cld
- rep movsw ; copy from page [si] to page [di]
- pop ds ; recover ds
- pop es ; and other registers
- pop cx
- ret
- hgasr endp
-
- dump proc FAR ; Write screen as TIFF v5.0 file
- push ax
- push bx
- push cx
- push dx
- push si
- push di
- call remcursor ; remove the cursor from the screen
- mov si,offset dumpname ; name of dump file
- mov di,offset rdbuf ; destination
- push es
- push ds
- pop es
- mov cx,dumplen ; length of dump name
- cld
- rep movsb ; copy it, asciiz
- pop es
- mov ax,offset rdbuf ; address to ax for unique
- call tunique ; get unique name into ax
- mov dx,ax ; ds:dx is asciiz filename
- xor cx,cx ; normal attributes
- mov ah,creat2 ; create the file
- int dos
- jc dmp3 ; c = failure
- dmp1: mov dhandle,ax ; file handle
- call dmpdate ; do time stamp
- cmp plotptr,offset pltcga ; using CGA style graphics?
- jne dmp2 ; ne = no
- call cgadmp ; do CGA style dump routine
- jmp short dmp3
- dmp2: call egadmp
- dmp3: jnc dmp5 ; nc = successful dump
- mov cx,4
- dmp4: push cx
- call tekbeep ; make a noise
- mov ax,250 ; wait 250ms
- call tekwait
- pop cx
- loop dmp4 ; four beeps
- dmp5: mov cursorst,1 ; pretend cursor was on
- call remcursor ; restore the cursor to the screen
- mov cursorst,1 ; say it is on
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
- ret
- dump endp
-
- ; CGA TIFF 5.0 screen-to-file dump routine
- cgadmp proc near
- push es ; do the bookkeeping math first
- mov bps.entval,1 ; bits/sample, mono
- mov photo.entval,1 ; mono, one bit after the other
- mov word ptr cmap.entcnt,0 ; no palette color map entries
- mov ax,xmax ; image width - 8 pixels
- add ax,8 ; plus 8, for pixels per line
- mov iwidth.entval,ax ; store in directory
- mov xresval,ax ; x resolution
- mov xresval+2,0 ; high order part
- mov ax,ybot ; lines per screen - 1
- inc ax ; lines per screen
- mov ilength.entval,ax ; image length, scan lines
- mov yresval,ax ; y resolution
- mov yresval+2,0 ; high order part
- mov cx,25 ; try dividing into this many strips
- cgadmp5:xor dx,dx ; image pixels
- mov ax,yresval ; number of scan lines
- div cx ; try dividing into 25 strips,ax=quo
- or dx,dx ; did we get null remainder?
- loopnz cgadmp5 ; nz = no, try again with fewer strips
- inc cx ; inc for dec by loop, cx = # strips
- mov word ptr strip.entcnt,cx ; store number of strips
- mov word ptr sbc.entcnt,cx ; store number of strip byte counts
- mov rps.entval,ax ; rows per strip
- push cx
- mov cx,iwidth.entval ; dots per line (row)
- shr cx,1 ; get bytes/row
- shr cx,1
- shr cx,1
- mul cx ; rows/strip * bytes/row = bytes/strip
- pop cx
- push cx ; save strip count for loop below
- push ds ; ax = bytes per strip
- pop es ; es:di to our data segment
- mov di,offset stripbc ; where to write strip byte counts
- cld
- rep stosw ; write ax as bytes/strip, cx times
- pop cx
- mov dx,ax ; bytes/strip = increment, put here
- mov di,offset stripoff ; where we write
- mov ax,offset pixdata-offset header ; where first strip starts
- cgadmp4:stosw ; write strip file offset
- mov word ptr [di],0 ; high order part
- add di,2 ; next double word
- add ax,dx ; next file strip offset
- loop cgadmp4 ; do all strip offsets
- ; file i/o starts here
- mov bx,dhandle ; dump's file handle
- mov dx,offset header ; write TIFF header and directory
- mov cx,tifflen ; length of header plus directory
- mov ah,write2
- int dos
- jc cgadmp2 ; c = failure
- xor di,di ; start at y = top
- call psetup ; setup cga and di
- mov cx,ybot ; number of scan lines-1
- inc cx ; number of scan lines
- cgadmp1:push cx
- mov cx,iwidth.entval ; dots per line (row)
- shr cx,1 ; get bytes/row
- shr cx,1
- shr cx,1 ; line length, bytes
- mov dx,di ; offset in screen buffer
- mov bx,dhandle ; file handle
- push ds
- mov ax,segscn ; screen seg
- mov ds,ax
- mov ah,write2 ; write directly from screen memory
- int dos
- pop ds
- jc cgadmp2 ; c = failure
- call pincy ; next line down, y = y + 1
- pop cx
- loop cgadmp1 ; do all scan lines
- cgadmp2:mov ah,close2 ; close the file
- int dos
- mov dhandle,-1 ; set handle to unused
- pop es
- ret
- cgadmp endp
-
- ; EGA TIFF 5.0 screen-to-file dump routine
- egadmp proc near
- push es ; do the bookkeeping math first
- mov bps.entval,4 ; bits/sample, iRGB
- mov photo.entval,3 ; photo interp, palette
- mov word ptr cmap.entcnt,3*16 ; palette color map entries
- mov ax,xmax ; image width - 8 pixels
- add ax,8 ; plus 8, for pixels per line
- mov iwidth.entval,ax ; store in directory
- mov xresval,ax ; x resolution
- mov xresval+2,0 ; high order part
- mov ax,ybot ; lines per screen - 1
- inc ax ; lines per screen
- mov ilength.entval,ax ; image length, scan lines
- mov yresval,ax ; y resolution
- mov yresval+2,0 ; high order part
- mov cx,25 ; try dividing into this many strips
- egadmp10:xor dx,dx ; image pixels
- mov ax,yresval ; number of scan lines
- div cx ; try dividing into 25 strips, ax=quo
- or dx,dx ; did we get null remainder?
- loopnz egadmp10 ; nz = no, try again with fewer strips
- inc cx ; inc for dec by loop, cx = # strips
- mov word ptr strip.entcnt,cx ; store number of strips
- mov word ptr sbc.entcnt,cx ; store number of strip byte counts
- mov rps.entval,ax ; rows per strip
- shl ax,1
- shl ax,1 ; times 4 bits / pixel
- push cx
- mov cx,iwidth.entval ; dots per line (row)
- shr cx,1 ; get bytes/row
- shr cx,1
- shr cx,1
- mul cx ; rows/strip * bytes/row = bytes/strip
- pop cx
- push cx ; save strip count for loop below
- push ds ; ax = bytes per strip
- pop es ; es:di to our data segment
- mov di,offset stripbc ; where to write strip byte counts
- cld
- rep stosw ; write ax as bytes/strip, cx times
- pop cx
- mov dx,ax ; bytes/strip = increment, put here
- mov di,offset stripoff ; where we write
- mov ax,offset pixdata-offset header ; where first strip starts
- xor bx,bx
- egadmp11:stosw ; write strip file offset
- mov es:[di],bx ; high order part
- add di,2 ; next double word
- add ax,dx ; next file strip offset
- adc bx,0
- loop egadmp11 ; do all strip offsets
- ; screen to file i/o starts here
- mov bx,dhandle ; dump's file handle
- mov dx,offset header ; write TIFF header and directory
- mov cx,tifflen ; length of header plus directory
- mov ah,write2
- int dos
- jnc egadmp12
- jmp egadmp9 ; c = failure
- egadmp12:
- xor di,di ; start at y = top
- call psetup ; setup adapter and es:di
- xor di,di
- mov bx,offset rdbuf ; set buffer address
- mov cx,ybot ; number of scan lines-1
- inc cx ; number of scan lines
- egadmp1:push cx ; save scan line counter
- mov cx,iwidth.entval ; dots per line (row)
- shr cx,1 ; get bytes/row
- shr cx,1
- shr cx,1 ; 8*dots across the screen (640)
- egadmp2:push cx ; save counter of inner loops
- mov cx,4 ; number of planes to do
- mov word ptr [bx],0 ; clear the four bytes for this loop
- mov word ptr [bx+2],0
- egadmp3:push cx ; save plane counter
- push bx ; don't advance buffer pointer here
- mov dx,3ceh ; (ega_gc)
- mov al,4 ; command to select read map register
- out dx,al ; output command code
- inc dx ; dx is now data port
- mov al,cl ; do planes 3(I), then 2(R),1(G),0(B)
- dec al ; cx is one higher than plane
- out dx,al ; output value (end of ega_gc)
- mov al,es:[di] ; latch byte
- ; got 8 bits from a plane
- mov cx,4 ; do this for four output bytes
- egadmp4:mov ah,[bx] ; eventually iRGB in each nibble
- shl al,1 ; get left most pixel bit in plane
- jnc egadmp5
- or ah,8 ; set high nibble least sig bit
- egadmp5:shl al,1 ; odd numbered pixel
- rcl ah,1 ; set low nibble least sig bit if c
- mov [bx],ah
- inc bx ; next byte
- loop egadmp4 ; do all four bytes
-
- pop bx
- pop cx ; restore plane counter
- loop egadmp3 ; do all planes
-
- inc di ; next screen memory address
- add bx,4 ; just did four bytes
- cmp bx,offset rdbuf+80 ; at end of 80 bytes?
- jb egadmp6 ; b = no
- call egadmpw ; write the buffer
- mov bx,offset rdbuf ; reset buffer address
- jnc egadmp6 ; nc = success
- pop cx ; clean stack
- pop cx
- jmp egadmp9 ; error
-
- egadmp6:pop cx ; recover bytes per line counter
- loop egadmp2 ; next group across scan line
- pop cx ; recover scan line counter
- loop egadmp1 ; do next scan line
- call egadmpw ; flush the buffer for last scan line
- egadmp9:mov ah,close2 ; close the file
- mov bx,dhandle
- int dos
- mov dhandle,-1 ; set handle to unused
- xor di,di
- call psetup
- pop es
- ret
- ; local worker
- egadmpw:push bx ; write tempbuf from start to [bx-1]
- push cx
- mov dx,offset rdbuf ; work buffer
- mov cx,bx ; buffer pointer to next free byte
- sub cx,dx ; buffer size to write
- cmp cx,0
- jle egadmpw1 ; le = nothing to write
- mov bx,dhandle ; file handle
- mov ah,write2 ; write cx bytes from rdbuf
- int dos
- jc egadmpw2 ; c = error
- cmp ax,cx ; wrote all?
- jne egadmpw2 ; ne = no
- egadmpw1:clc ; clc
- pop cx
- pop bx
- ret
- egadmpw2:stc ; carry set for failure
- pop cx
- pop bx
- ret
- egadmp endp
-
- ; Worker. Write Kermit version and current date and time in TIFF header
- dmpdate proc near
- mov di,offset prog+10 ; place for version in prog field
- mov ax,version ; Kermit version
- call dec2di ; write the version
- mov ah,getdate ; DOS date (cx= yyyy, dh= mm, dl= dd)
- int dos
- mov di,offset dandt ; where to write
- mov ax,cx ; get yyyy
- push dx
- call dec2di ; write to buffer
- pop dx
- mov byte ptr [di],':'
- inc di
- mov al,dh ; mm
- cmp al,10 ; leading digit?
- jae dmpdat1 ; ae = yes
- mov byte ptr [di],'0' ; make our own
- inc di
- dmpdat1:xor ah,ah
- push dx
- call dec2di
- mov byte ptr [di],':'
- pop dx
- inc di
- mov al,dl ; dd
- cmp al,10 ; leading digit?
- jae dmpdat2 ; ae = yes
- mov byte ptr [di],'0' ; make our own
- inc di
- dmpdat2:xor ah,ah
- call dec2di
- mov byte ptr [di],' '
- inc di
- mov ah,gettim ; DOS tod (ch=hh, cl=mm, dh=ss, dl=.s)
- int dos
- push dx ; save dx
- xor ah,ah
- mov al,ch ; Hours
- cmp al,10 ; leading digit?
- jae dmpdat3 ; ae = yes
- mov byte ptr [di],'0' ; make our own
- inc di
- dmpdat3:push cx
- call dec2di ; write decimal asciiz to buffer
- pop cx
- mov byte ptr [di],':'
- inc di
- xor ah,ah
- mov al,cl ; Minutes
- cmp al,10 ; leading digit?
- jae dmpdat4 ; ae = yes
- mov byte ptr [di],'0' ; make our own
- inc di
- dmpdat4:call dec2di ; write decimal asciiz to buffer
- mov byte ptr [di],':'
- inc di
- pop dx
- xor ah,ah
- mov al,dh ; Seconds
- cmp al,10 ; leading digit?
- jae dmpdat5 ; ae = yes
- mov byte ptr [di],'0' ; make our own
- inc di
- dmpdat5:call dec2di ; write decimal asciiz to buffer
- inc di
- ret
- dmpdate endp
-
- ; Read 8x14 GRight font for current Code Page from DOS file EGA.CPI to
- ; array fontgright. Returns carry set if failed.
- getfont proc near
- mov ax,offset fontfile ; EGA.CPI filename
- call fspath ; search path for it
- jnc getfont1 ; nc = found, ax has full path
- ret ; not found, fail
- getfont1:mov dx,ax ; point to name from spath
- mov ah,open2 ; open file
- xor al,al ; 0 = open for reading
- cmp dosnum,300h ; at or above DOS 3?
- jb getfont2 ; b = no, so no shared access
- or al,40h ; open for reading, deny none
- getfont2:int dos
- jnc getfont3 ; nc = success
- ret ; failure
-
- getfont3:mov temp,ax ; file handle
- mov bx,ax ; handle
- mov cx,23 ; read "head" information, 23 bytes
- mov dx,offset stripoff ; ds:dx = temp work buffer
- mov ah,readf2 ; read file
- int dos
- jnc getfont4 ; nc = successful read
- getfont3a:jmp getfont12 ; fail
-
- getfont4:cmp byte ptr stripoff,0ffh ; file signature
- jne getfont3a ; ne = not a CPI file internally
- mov dx,word ptr stripoff[19] ; offset of word "info"
- mov cx,word ptr stripoff[21] ; high order part
- mov ah,lseek
- xor al,al ; seek from BOF
- int dos
- mov cx,2 ; read a word
- mov dx,offset stripoff
- mov ah,readf2
- int dos
- mov di,word ptr stripoff ; number of Code Page entities
-
- getfont6:mov bx,temp ; handle
- mov cx,128 ; buffer with font info
- mov dx,offset stripoff
- mov ah,readf2
- int dos
- cmp word ptr stripoff[8],'GE' ; "EGA"?
- jne getfont7 ; ne = no, keep looking
- mov dx,vtcpage ; current Code Page
- cmp word ptr stripoff[16],dx ; Code Page ident, same?
- je getfont8 ; e = yes
- getfont7:mov dx,word ptr stripoff[2] ; ptr to next CP entry
- mov cx,word ptr stripoff[4] ; high order part
- mov bx,temp ; file handle for seeking
- mov ah,lseek
- xor al,al ; seek from BOF
- int dos
- dec di ; one less Code Page
- cmp di,0 ; done all?
- jg getfont6 ; g = no, get next header
- stc ; failed to find CP material
- jmp getfont12 ; fail
- ; found CP section, find fonts
- getfont8:mov dx,word ptr stripoff[24] ; offset of fonts data
- mov cx,word ptr stripoff[26] ; high order part
- mov ah,lseek
- xor al,al ; seek from BOF
- int dos
- mov bx,temp ; handle
- mov cx,6 ; read font's "dathead"
- mov dx,offset stripoff
- mov ah,readf2
- int dos
- mov di,word ptr stripoff[2] ; number of fonts in this CP item
-
- getfont9:mov bx,temp ; handle
- mov cx,6 ; read fonthead: hgt,width,0,0,# chars
- mov dx,offset stripoff
- mov ah,readf2
- int dos
- mov ax,word ptr stripoff ; cell height (low byte)
- push ax ; save for test below
- mov cl,ah ; cell width (typically 8)
- mul cl ; number of bytes per char
- mul word ptr stripoff[4] ; number chars in table=bits to skip
- mov cx,8 ; divide by 8 for bytes, hope is ok
- div cx
- xor cx,cx ; high part, for lseek
- mov dx,ax ; low part (whole bytes)
- pop ax
- cmp ax,8*256+14 ; is this font 14x8?
- je getfont10 ; e = yes, that is what we want
- mov bx,temp ; handle
- mov ah,lseek
- mov al,1 ; seek from current position
- int dos
- dec di ; one less font in this CP section
- cmp di,0 ; done all?
- jg getfont9 ; g = no
- stc
- jmp short getfont12 ; fail
- ; read the 8x14 patterns
- getfont10:mov dx,128*14 ; bytes in GLeft patterns (128 chars)
- xor cx,cx
- mov bx,temp ; handle
- mov ah,lseek
- mov al,1 ; seek from current position
- int dos
- ; malloc memory for font table
- mov bx,(128*14)/16 ; paragraphs for 128*14 bytes
- mov cx,bx ; remember desired paragraphs
- mov ah,alloc ; allocate a memory block
- int dos
- jc getfont12 ; c = error, not enough memory
- cmp bx,cx ; obtained vs wanted
- jae getfont11 ; ae = enough
- mov es,ax ; allocated segment
- mov ah,freemem ; free it
- int dos
- jmp short getfont12 ; quit here
-
- getfont11:mov word ptr fontrptr+2,ax ; address of allocated memory
- mov word ptr fontrptr,0 ; offset is zero
- mov cx,128*14 ; bytes in GRight patterns
- mov bx,temp ; handle
- push ds
- mov ds,ax
- xor dx,dx ; ds:dx is buffer, from malloc
- mov ah,readf2
- int dos
- pop ds
- jnc getfont12 ; nc = success
- mov ax,word ptr fontrptr+2 ; get segment
- mov es,ax ; allocated segment
- mov ah,freemem ; free it
- int dos
- stc ; say failure
- getfont12:pushf ; save carry bit
- mov bx,temp ; handle
- mov ah,close2 ; close file
- int dos
- popf
- ret
- getfont endp
-
- ; Dispatch table processor. Enter with BX pointing at table of {char count,
- ; address of action routines, characters}. Jump to matching routine or return.
- ; Enter with AL holding received Final char.
- atdispat proc near
- mov cl,[bx] ; get table length from first byte
- xor ch,ch
- mov di,bx ; main table
- add di,3 ; point di at first char in table
- push es
- push ds
- pop es ; use data segment for es:di below
- cld ; set direction forward
- repne scasb ; find matching character
- pop es
- je atdisp2 ; e = found a match, get action addr
- cmp al,' ' ; control char?
- jb atdisp1 ; b = yes
- ret ; ignore escape sequence
- atdisp1:jmp tekctl ; process control char
- atdisp2:sub di,bx ; distance scanned in table
- sub di,4 ; skip count byte, address word, inc
- shl di,1 ; convert to word index
- inc bx ; point to address of action routines
- mov bx,[bx] ; get address of action table
- jmp word ptr [bx+di] ; dispatch to the routine
- atdispat endp
-
- ansich proc near ; insert Pn spaces at and after cursor
- mov cx,param ; get Pn
- or cx,cx
- jnz ansich1 ; got a value
- inc cx ; zero means one
- ansich1:push x_coord
- push y_coord
- and x_coord,not 7 ; modulo 8x8 cells
- mov ax,xmax ; start of last cell
- sub ax,x_coord ; start of current cell
- shr ax,1 ; divide by 8 dots per char
- shr ax,1
- shr ax,1
- cmp ax,cx ; want more spaces than are on line?
- jae ansich2 ; ae = no
- mov cx,ax ; clip to right margin
- jcxz ansich3 ; z = nothing to do
- ansich2:push cx
- mov al,' ' ; a space
- call putc ; write to screen
- pop cx
- loop ansich2 ; do them
- ansich3:pop x_coord
- pop y_coord
- call remcursor ; remove text cursor symbol
- call setcursor ; draw cursor at new location
- ret
- ansich endp
- ; scaled by text screen height
- atcuu proc near ; cursor up Pn lines
- cmp param,0 ; empty arg?
- jne atcuu1 ; got a value
- inc param ; zero means one
- atcuu1: mov ax,y_coord ; where we are now
- add ax,4 ; round up a smidge
- mov cl,byte ptr low_rgt+1 ; highest text line
- xor ch,ch
- mul cx ; proportion
- xor dx,dx
- mov cx,ybot ; highest scan line
- div cx ; end, estimate currren text line
- sub ax,param
- inc ax ; count lines from 1 again
- mov param,ax ; new text row
- jmp atcva ; do as absolute
- atcuu endp
-
- ; scaled by text screen height
- atcud proc near ; cursor down Pn lines
- cmp param,0 ; get Pn
- jne atcud1 ; ne = got a value
- inc param ; zero means one
- atcud1: mov ax,y_coord ; where we are now
- add ax,4 ; round up a smidge
- mov cl,byte ptr low_rgt+1 ; highest text line
- xor ch,ch
- mul cx ; proportion
- xor dx,dx
- mov cx,ybot ; highest scan line
- div cx ; end, estimate currren text line
- inc ax ; count lines from 1 again
- add param,ax ; new text row
- jmp atcva ; do as absolute
- atcud endp
-
- atcuf proc near ; cursor forward Pn columns
- mov ax,param ; get Pn
- or ax,ax
- jnz atcuf1 ; got a value
- inc ax ; zero means one
- atcuf1: shl ax,1 ; times 8 dots per char cell
- shl ax,1
- shl ax,1 ; Tek columns worth
- and x_coord,not 7 ; modulo 8x8 cells
- add x_coord,ax ; forward to absolute column
- mov ax,xmax
- cmp x_coord,ax ; beyond right most cell?
- jbe atcuf2 ; be = no
- mov x_coord,ax ; limit to right
- atcuf2: call remcursor ; remove text cursor symbol
- call setcursor ; draw cursor at new location
- ret
- atcuf endp
-
- atcub proc near ; cursor left/back Pn columns
- mov ax,param ; get Pn
- or ax,ax
- jnz atcub1 ; got a value
- inc ax ; zero means one
- atcub1: shl ax,1
- shl ax,1
- shl ax,1 ; times 8 dots per cell
- and x_coord,not 7 ; modulo 8x8 cells
- mov cx,xmax
- cmp x_coord,cx ; beyond last col (wrap pending)?
- jbe atcub3 ; be = no
- mov x_coord,cx ; set to last col
- atcub3: sub x_coord,ax ; back up
- jnc atcub2 ; nc = ok
- mov x_coord,0 ; stop in column zero
- atcub2: call remcursor ; remove text cursor symbol
- call setcursor ; draw cursor at new location
- ret
- atcub endp
-
- atcnl proc near ; do Pn cr/lf's
- mov x_coord,0 ; to left margin
- jmp atcud ; do the cursor downs
- atcnl endp
-
- atcpl proc near ; do Pn cursor ups
- jmp atcuu ; do the cursor ups
- atcpl endp
-
- ; scaled by text screen width
- atcha proc near ; cursor to absolute column
- and x_coord,not 7 ; modulo 8x8 cells
- mov ax,param ; get Pn
- or ax,ax
- jz atcha1 ; z = zero already
- dec param ; count columns from 0
- mov ax,xmax ; number of Tek dots/row
- mul param ; times columns they want
- mov cl,byte ptr low_rgt ; number of last text column
- xor ch,ch
- xor dx,dx
- div cx ; scale to ~80 column screen
- cmp ax,xmax ; too far?
- jbe atcha1 ; be = no
- mov ax,xmax ; right most column
- atcha1: mov x_coord,ax
- call remcursor ; remove text cursor symbol
- call setcursor ; draw cursor at new location
- ret
- atcha endp
- ; scaled by text screen height
- atcva proc near ; cursor to absolute row
- dec param ; count from 0
- mov ax,param ; desired text row
- or ax,ax ; zero or now -1?
- jg atcva1 ; g = no, further down
- mov ax,7 ; bottom of top text cell
- jmp short atcva2
- atcva1: mov ax,ybot
- inc ax ; number of scan lines on screen
- ;;;; and ax,not 7 ; whole 8x8 char cells
- mul param ; times row they want
- mov cl,byte ptr low_rgt+1 ; number of last text line (0..23)
- xor ch,ch
- xor dx,dx
- div cx ; scale to ~24 line screen
- mov cx,ybot
- ;;;; and cx,not 7 ; whole 8x8 char cells
- cmp ax,cx ; too far?
- jbe atcva2 ; be = no
- mov ax,cx
- atcva2: mov y_coord,ax ; go to that line
- call remcursor ; remove text cursor symbol
- call setcursor ; draw cursor at new location
- ret
- atcva endp
-
- atcup proc near ; cursor to absolute row, column
- call atcva ; process param[0] as absolute row
- push param[2] ; column
- pop param
- jmp atcha ; process param[2] as absolute column
- atcup endp
-
- ated proc near ; erase display
- mov al,spcontrol ; preserve space control
- mov rdbuf,al ; save here
- mov spcontrol,1 ; turn on destructive space
- push x_coord
- push y_coord ; save cursor
- cmp param,0 ; cursor to end of screen?
- je ated1 ; e = yes
- cmp param,1 ; start of screen to cursor?
- je ated3 ; e = yes
- cmp param,2 ; entire screen?
- je ated5 ; e = yes
- ret ; else ignore
-
- ated1: mov param,0 ; cursor to end of this line
- call atel ; erase cursor to end of line
- add y_coord,8 ; look at next line
- mov ax,ybot
- cmp y_coord,ax ; are we at the end now?
- ja ated6 ; a = yes
- mov x_coord,0 ; start of line is here
- jmp ated1 ; do through last line
-
- ated3: and y_coord,not 7 ; modulo 8x8 char cells
- mov cx,y_coord ; start of screen to cursor
- shr cx,1 ; char lines at 8 dots/char
- shr cx,1
- shr cx,1
- dec cx ; omit current line= # whole lines
- or cx,cx ; any whole lines?
- jle ated3b ; le = no
- mov y_coord,7 ; start at the top line
- ated3a: push cx
- mov param,2 ; entire line
- call atel ; erase entire line
- add y_coord,8 ; next line
- pop cx
- loop ated3a
- ated3b: mov param,1 ; start of line to cursor
- call atel ; erase to cursor on this (last) line
- jmp short ated6
-
- ated5: call tekcls ; erase whole screen
-
- ated6: mov al,rdbuf ; spacing control
- mov spcontrol,al
- pop y_coord
- pop x_coord
- call remcursor ; remove last cursor
- call setcursor ; set cursor to original position
- ret
- ated endp
-
- atech proc near ; erase Pn chars from cursor to eol
- mov al,spcontrol ; preserve space control
- mov rdbuf,al ; save here
- mov spcontrol,1 ; turn on destructive space
- push x_coord
- push y_coord ; save cursor
- mov cx,x_coord
- and cx,not 7 ; modulo 8x8 cells
- mov ax,xmax
- sub ax,cx ; number of chars remaining on line
- shr ax,1
- shr ax,1
- shr ax,1
- inc ax ; count cursor cell
- mov cx,param ; how many chars to erase
- or cx,cx
- jz atech1 ; z = zero, use one
- inc cx
- atech1: cmp ax,cx ; want more than line length?
- jae atech2 ; ae = no
- mov cx,ax ; clip at right margin
- or cx,cx
- jle atech3 ; le = nothing to do
- atech2: push cx
- mov al,' '
- call outscrn ; write spaces
- pop cx
- loop atech2
- atech3: mov al,rdbuf ; spacing control
- mov spcontrol,al
- pop y_coord
- pop x_coord
- call remcursor ; remove last cursor
- call setcursor ; set cursor to original position
- ret
- atech endp
-
- atel proc near ; erase on this line
- call remcursor ; remove cursor
- push x_coord
- push y_coord
- cmp param,0 ; cursor to end of line?
- je atel1 ; e = yes
- cmp param,1 ; start of line to cursor?
- je atel3 ; e = yes
- cmp param,2 ; whole line?
- jne atel5 ; ne = no, fail
- mov x_coord,0 ; erase entire line
-
- atel1: mov cx,xmax ; cursor to end of line
- mov ax,x_coord
- and ax,not 7 ; modulo 8x8 cells
- sub cx,ax
- shr cx,1
- shr cx,1
- shr cx,1 ; 8 dots/char
- inc cx ; count the cursor cell
- or cx,cx
- jle atel5 ; le = do nothing
- mov al,spcontrol ; preserve space control
- mov rdbuf,al ; save here
- mov spcontrol,1 ; turn on destructive space
- atel2: push cx ; start of line to cursor
- mov al,' '
- call outscrn
- pop cx
- loop atel2
- mov al,rdbuf ; space control
- mov spcontrol,al ; restored
- atel5: pop y_coord
- pop x_coord
- call remcursor ; remove last cursor
- call setcursor ; set cursor to original position
- ret
- atel3: mov cx,x_coord ; start of line to cursor
- shr cx,1
- shr cx,1
- shr cx,1
- inc cx ; count cursor cell
- mov x_coord,0 ; go to start of line
- jmp atel2 ; do the loops
- atel endp
- code2 ends
- end
-